hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/8254Timer.inf b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
new file mode 100644
index 0000000..67493d1
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
@@ -0,0 +1,48 @@
+## @file

+# 8254 timer driver that provides Timer Arch protocol.

+#

+# Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>

+# 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.             

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Timer

+  MODULE_UNI_FILE                = Timer.uni

+  FILE_GUID                      = f2765dec-6b41-11d5-8e71-00902707b35e

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = TimerDriverInitialize

+

+[Packages]

+  MdePkg/MdePkg.dec

+  IntelFrameworkPkg/IntelFrameworkPkg.dec

+  

+[LibraryClasses]

+  UefiBootServicesTableLib

+  BaseLib

+  DebugLib

+  UefiDriverEntryPoint

+  IoLib

+

+[Sources]

+  Timer.h

+  Timer.c

+

+[Protocols]

+  gEfiCpuArchProtocolGuid       ## CONSUMES 

+  gEfiLegacy8259ProtocolGuid    ## CONSUMES

+  gEfiTimerArchProtocolGuid     ## PRODUCES

+

+[Depex]

+  gEfiCpuArchProtocolGuid AND gEfiLegacy8259ProtocolGuid

+[UserExtensions.TianoCore."ExtraFiles"]

+  TimerExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.c b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.c
new file mode 100644
index 0000000..a7f4947
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.c
@@ -0,0 +1,407 @@
+/** @file

+  Timer Architectural Protocol as defined in the DXE CIS

+

+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>

+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.             

+

+**/

+

+#include "Timer.h"

+

+//

+// The handle onto which the Timer Architectural Protocol will be installed

+//

+EFI_HANDLE                mTimerHandle = NULL;

+

+//

+// The Timer Architectural Protocol that this driver produces

+//

+EFI_TIMER_ARCH_PROTOCOL   mTimer = {

+  TimerDriverRegisterHandler,

+  TimerDriverSetTimerPeriod,

+  TimerDriverGetTimerPeriod,

+  TimerDriverGenerateSoftInterrupt

+};

+

+//

+// Pointer to the CPU Architectural Protocol instance

+//

+EFI_CPU_ARCH_PROTOCOL     *mCpu;

+

+//

+// Pointer to the Legacy 8259 Protocol instance

+//

+EFI_LEGACY_8259_PROTOCOL  *mLegacy8259;

+

+//

+// The notification function to call on every timer interrupt.

+// A bug in the compiler prevents us from initializing this here.

+//

+EFI_TIMER_NOTIFY mTimerNotifyFunction;

+

+//

+// The current period of the timer interrupt

+//

+volatile UINT64           mTimerPeriod = 0;

+

+//

+// Worker Functions

+//

+/**

+  Sets the counter value for Timer #0 in a legacy 8254 timer.

+

+  @param Count    The 16-bit counter value to program into Timer #0 of the legacy 8254 timer.

+**/

+VOID

+SetPitCount (

+  IN UINT16  Count

+  )

+{

+  IoWrite8 (TIMER_CONTROL_PORT, 0x36);

+  IoWrite8 (TIMER0_COUNT_PORT, (UINT8)(Count & 0xff));

+  IoWrite8 (TIMER0_COUNT_PORT, (UINT8)((Count >> 8) & 0xff));

+}

+

+/**

+  8254 Timer #0 Interrupt Handler.

+

+  @param InterruptType    The type of interrupt that occured

+  @param SystemContext    A pointer to the system context when the interrupt occured

+**/

+VOID

+EFIAPI

+TimerInterruptHandler (

+  IN EFI_EXCEPTION_TYPE   InterruptType,

+  IN EFI_SYSTEM_CONTEXT   SystemContext

+  )

+{

+  EFI_TPL OriginalTPL;

+

+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+

+  mLegacy8259->EndOfInterrupt (mLegacy8259, Efi8259Irq0);

+

+  if (mTimerNotifyFunction != NULL) {

+    //

+    // @bug : This does not handle missed timer interrupts

+    //

+    mTimerNotifyFunction (mTimerPeriod);

+  }

+

+  gBS->RestoreTPL (OriginalTPL);

+}

+

+/**

+

+  This function registers the handler NotifyFunction so it is called every time

+  the timer interrupt fires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is

+  returned.  If the CPU does not support registering a timer interrupt handler,

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR

+  is returned.

+

+

+  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param NotifyFunction   The function to call when a timer interrupt fires.  This

+                          function executes at TPL_HIGH_LEVEL.  The DXE Core will

+                          register a handler for the timer interrupt, so it can know

+                          how much time has passed.  This information is used to

+                          signal timer based events.  NULL will unregister the handler.

+

+  @retval        EFI_SUCCESS            The timer handler was registered.

+  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.

+  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already

+                                        registered.

+  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not

+                                        previously registered.

+  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+{

+  //

+  // Check for invalid parameters

+  //

+  if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  mTimerNotifyFunction = NotifyFunction;

+

+  return EFI_SUCCESS;

+}

+

+/**

+

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+

+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If

+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is

+                         returned.  If the timer is programmable, then the timer period

+                         will be rounded up to the nearest timer period that is supported

+                         by the timer hardware.  If TimerPeriod is set to 0, then the

+                         timer interrupts will be disabled.

+

+  @retval        EFI_SUCCESS       The timer period was changed.

+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.

+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+{

+  UINT64  TimerCount;

+

+  //

+  //  The basic clock is 1.19318 MHz or 0.119318 ticks per 100 ns.

+  //  TimerPeriod * 0.119318 = 8254 timer divisor. Using integer arithmetic

+  //  TimerCount = (TimerPeriod * 119318)/1000000.

+  //

+  //  Round up to next highest integer. This guarantees that the timer is

+  //  equal to or slightly longer than the requested time.

+  //  TimerCount = ((TimerPeriod * 119318) + 500000)/1000000

+  //

+  // Note that a TimerCount of 0 is equivalent to a count of 65,536

+  //

+  // Since TimerCount is limited to 16 bits for IA32, TimerPeriod is limited

+  // to 20 bits.

+  //

+  if (TimerPeriod == 0) {

+    //

+    // Disable timer interrupt for a TimerPeriod of 0

+    //

+    mLegacy8259->DisableIrq (mLegacy8259, Efi8259Irq0);

+  } else {

+

+    //

+    // Convert TimerPeriod into 8254 counts

+    //

+    TimerCount = DivU64x32 (MultU64x32 (119318, (UINT32) TimerPeriod) + 500000, 1000000);

+

+    //

+    // Check for overflow

+    //

+    if (TimerCount >= 65536) {

+      TimerCount = 0;

+      TimerPeriod = MAX_TIMER_TICK_DURATION;

+    }

+    //

+    // Program the 8254 timer with the new count value

+    //

+    SetPitCount ((UINT16) TimerCount);

+

+    //

+    // Enable timer interrupt

+    //

+    mLegacy8259->EnableIrq (mLegacy8259, Efi8259Irq0, FALSE);

+  }

+  //

+  // Save the new timer period

+  //

+  mTimerPeriod = TimerPeriod;

+

+  return EFI_SUCCESS;

+}

+

+/**

+

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+

+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If

+                         0 is returned, then the timer is currently disabled.

+

+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.

+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mTimerPeriod;

+

+  return EFI_SUCCESS;

+}

+

+/**

+

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+

+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS       The soft timer interrupt was generated.

+  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      IRQMask;

+  EFI_TPL     OriginalTPL;

+  

+  //

+  // If the timer interrupt is enabled, then the registered handler will be invoked.

+  //

+  Status = mLegacy8259->GetMask (mLegacy8259, NULL, NULL, &IRQMask, NULL);

+  ASSERT_EFI_ERROR (Status);

+  if ((IRQMask & 0x1) == 0) {

+    //

+    // Invoke the registered handler

+    //

+    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+

+    if (mTimerNotifyFunction != NULL) {

+      //

+      // @bug : This does not handle missed timer interrupts

+      //

+      mTimerNotifyFunction (mTimerPeriod);

+    }

+   

+    gBS->RestoreTPL (OriginalTPL);

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Initialize the Timer Architectural Protocol driver

+

+  @param ImageHandle     ImageHandle of the loaded driver

+  @param SystemTable     Pointer to the System Table

+

+  @retval EFI_SUCCESS            Timer Architectural Protocol created

+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.

+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  UINT32      TimerVector;

+

+  //

+  // Initialize the pointer to our notify function.

+  //

+  mTimerNotifyFunction = NULL;

+

+  //

+  // Make sure the Timer Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);

+

+  //

+  // Find the CPU architectural protocol.

+  //

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Find the Legacy8259 protocol.

+  //

+  Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Force the timer to be disabled

+  //

+  Status = TimerDriverSetTimerPeriod (&mTimer, 0);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver

+  //

+  TimerVector = 0;

+  Status      = mLegacy8259->GetVector (mLegacy8259, Efi8259Irq0, (UINT8 *) &TimerVector);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Install interrupt handler for 8254 Timer #0 (ISA IRQ0)

+  //

+  Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Force the timer to be enabled at its default period

+  //

+  Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Install the Timer Architectural Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mTimerHandle,

+                  &gEfiTimerArchProtocolGuid, &mTimer,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.h b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.h
new file mode 100644
index 0000000..5a354a8
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.h
@@ -0,0 +1,191 @@
+/** @file

+  Private data structures

+

+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>

+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.             

+**/

+

+#ifndef _TIMER_H_

+#define _TIMER_H_

+

+#include <PiDxe.h>

+

+#include <Protocol/Cpu.h>

+#include <Protocol/Legacy8259.h>

+#include <Protocol/Timer.h>

+

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+

+//

+// The PCAT 8253/8254 has an input clock at 1.193182 MHz and Timer 0 is

+// initialized as a 16 bit free running counter that generates an interrupt(IRQ0)

+// each time the counter rolls over.

+//

+//   65536 counts

+// ---------------- * 1,000,000 uS/S = 54925.4 uS = 549254 * 100 ns

+//   1,193,182 Hz

+//

+

+//

+// The maximum tick duration for 8254 timer

+//

+#define MAX_TIMER_TICK_DURATION     549254

+//

+// The default timer tick duration is set to 10 ms = 100000 100 ns units

+//

+#define DEFAULT_TIMER_TICK_DURATION 100000

+#define TIMER_CONTROL_PORT          0x43

+#define TIMER0_COUNT_PORT           0x40

+

+//

+// Function Prototypes

+//

+/**

+  Initialize the Timer Architectural Protocol driver

+

+  @param ImageHandle     ImageHandle of the loaded driver

+  @param SystemTable     Pointer to the System Table

+

+  @retval EFI_SUCCESS            Timer Architectural Protocol created

+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.

+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+;

+

+/**

+

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+

+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If

+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is

+                         returned.  If the timer is programmable, then the timer period

+                         will be rounded up to the nearest timer period that is supported

+                         by the timer hardware.  If TimerPeriod is set to 0, then the

+                         timer interrupts will be disabled.

+

+  @retval        EFI_SUCCESS       The timer period was changed.

+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.

+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+;

+

+/**

+

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+

+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If

+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is

+                         returned.  If the timer is programmable, then the timer period

+                         will be rounded up to the nearest timer period that is supported

+                         by the timer hardware.  If TimerPeriod is set to 0, then the

+                         timer interrupts will be disabled.

+

+  @retval        EFI_SUCCESS       The timer period was changed.

+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.

+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+;

+

+/**

+

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+

+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If

+                         0 is returned, then the timer is currently disabled.

+

+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.

+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+;

+

+/**

+

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+

+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS       The soft timer interrupt was generated.

+  @retval EFI_UNSUPPORTEDT  The platform does not support the generation of soft timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+;

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.uni b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.uni
new file mode 100644
index 0000000..aea2e73
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/Timer.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/TimerExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/TimerExtra.uni
new file mode 100644
index 0000000..e200747
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8254TimerDxe/TimerExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
new file mode 100644
index 0000000..e73a100
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
@@ -0,0 +1,628 @@
+/** @file

+  This contains the installation function for the driver.

+

+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+#include "8259.h"

+

+//

+// Global for the Legacy 8259 Protocol that is produced by this driver

+//

+EFI_LEGACY_8259_PROTOCOL  mInterrupt8259 = {

+  Interrupt8259SetVectorBase,

+  Interrupt8259GetMask,

+  Interrupt8259SetMask,

+  Interrupt8259SetMode,

+  Interrupt8259GetVector,

+  Interrupt8259EnableIrq,

+  Interrupt8259DisableIrq,

+  Interrupt8259GetInterruptLine,

+  Interrupt8259EndOfInterrupt

+};

+

+//

+// Global for the handle that the Legacy 8259 Protocol is installed

+//

+EFI_HANDLE                m8259Handle             = NULL;

+

+UINT8                     mMasterBase             = 0xff;

+UINT8                     mSlaveBase              = 0xff;

+EFI_8259_MODE             mMode                   = Efi8259ProtectedMode;

+UINT16                    mProtectedModeMask      = 0xffff;

+UINT16                    mLegacyModeMask;

+UINT16                    mProtectedModeEdgeLevel = 0x0000;

+UINT16                    mLegacyModeEdgeLevel;

+

+//

+// Worker Functions

+//

+

+/**

+  Write to mask and edge/level triggered registers of master and slave PICs.

+

+  @param[in]  Mask       low byte for master PIC mask register,

+                         high byte for slave PIC mask register.

+  @param[in]  EdgeLevel  low byte for master PIC edge/level triggered register,

+                         high byte for slave PIC edge/level triggered register.

+

+**/

+VOID

+Interrupt8259WriteMask (

+  IN UINT16  Mask,

+  IN UINT16  EdgeLevel

+  )

+{

+  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, (UINT8) Mask);

+  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8) (Mask >> 8));

+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8) EdgeLevel);

+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8) (EdgeLevel >> 8));

+}

+

+/**

+  Read from mask and edge/level triggered registers of master and slave PICs.

+

+  @param[out]  Mask       low byte for master PIC mask register,

+                          high byte for slave PIC mask register.

+  @param[out]  EdgeLevel  low byte for master PIC edge/level triggered register,

+                          high byte for slave PIC edge/level triggered register.

+

+**/

+VOID

+Interrupt8259ReadMask (

+  OUT UINT16  *Mask,

+  OUT UINT16  *EdgeLevel

+  )

+{

+  UINT16  MasterValue;

+  UINT16  SlaveValue;

+

+  if (Mask != NULL) {

+    MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);

+    SlaveValue  = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);

+

+    *Mask = (UINT16) (MasterValue | (SlaveValue << 8));

+  }

+

+  if (EdgeLevel != NULL) {

+    MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);

+    SlaveValue  = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);

+

+    *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));

+  }

+}

+

+//

+// Legacy 8259 Protocol Interface Functions

+//

+

+/**

+  Sets the base address for the 8259 master and slave PICs.

+

+  @param[in]  This        Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  MasterBase  Interrupt vectors for IRQ0-IRQ7.

+  @param[in]  SlaveBase   Interrupt vectors for IRQ8-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while writing to the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetVectorBase (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN UINT8                     MasterBase,

+  IN UINT8                     SlaveBase

+  )

+{

+  UINT8   Mask;

+  EFI_TPL OriginalTpl;

+

+  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+  //

+  // Set vector base for slave PIC

+  //

+  if (SlaveBase != mSlaveBase) {

+    mSlaveBase = SlaveBase;

+

+    //

+    // Initialization sequence is needed for setting vector base.

+    //

+

+    //

+    // Preserve interrtup mask register before initialization sequence

+    // because it will be cleared during intialization

+    //

+    Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);

+

+    //

+    // ICW1: cascade mode, ICW4 write required

+    //

+    IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);

+

+    //

+    // ICW2: new vector base (must be multiple of 8)

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);

+

+    //

+    // ICW3: slave indentification code must be 2

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);

+

+    //

+    // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);

+

+    //

+    // Restore interrupt mask register

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);

+  }

+

+  //

+  // Set vector base for master PIC

+  //

+  if (MasterBase != mMasterBase) {

+    mMasterBase = MasterBase;

+

+    //

+    // Initialization sequence is needed for setting vector base.

+    //

+

+    //

+    // Preserve interrtup mask register before initialization sequence

+    // because it will be cleared during intialization

+    //

+    Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);

+

+    //

+    // ICW1: cascade mode, ICW4 write required

+    //

+    IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);

+

+    //

+    // ICW2: new vector base (must be multiple of 8)

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);

+

+    //

+    // ICW3: slave PIC is cascaded on IRQ2

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);

+

+    //

+    // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);

+

+    //

+    // Restore interrupt mask register

+    //

+    IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);

+  }

+

+  IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);

+  IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);

+  

+  gBS->RestoreTPL (OriginalTpl);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.

+

+  @param[in]   This                Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[out]  LegacyMask          16-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[out]  LegacyEdgeLevel     16-bit mode edge/level mask for IRQ-IRQ15.

+  @param[out]  ProtectedMask       32-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[out]  ProtectedEdgeLevel  32-bit mode edge/level mask for IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while reading the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetMask (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  OUT UINT16                    *LegacyMask, OPTIONAL

+  OUT UINT16                    *LegacyEdgeLevel, OPTIONAL

+  OUT UINT16                    *ProtectedMask, OPTIONAL

+  OUT UINT16                    *ProtectedEdgeLevel OPTIONAL

+  )

+{

+  if (LegacyMask != NULL) {

+    *LegacyMask = mLegacyModeMask;

+  }

+

+  if (LegacyEdgeLevel != NULL) {

+    *LegacyEdgeLevel = mLegacyModeEdgeLevel;

+  }

+

+  if (ProtectedMask != NULL) {

+    *ProtectedMask = mProtectedModeMask;

+  }

+

+  if (ProtectedEdgeLevel != NULL) {

+    *ProtectedEdgeLevel = mProtectedModeEdgeLevel;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.

+

+  @param[in]  This                Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  LegacyMask          16-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[in]  LegacyEdgeLevel     16-bit mode edge/level mask for IRQ-IRQ15.

+  @param[in]  ProtectedMask       32-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[in]  ProtectedEdgeLevel  32-bit mode edge/level mask for IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while writing the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetMask (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN UINT16                    *LegacyMask, OPTIONAL

+  IN UINT16                    *LegacyEdgeLevel, OPTIONAL

+  IN UINT16                    *ProtectedMask, OPTIONAL

+  IN UINT16                    *ProtectedEdgeLevel OPTIONAL

+  )

+{

+  if (LegacyMask != NULL) {

+    mLegacyModeMask = *LegacyMask;

+  }

+

+  if (LegacyEdgeLevel != NULL) {

+    mLegacyModeEdgeLevel = *LegacyEdgeLevel;

+  }

+

+  if (ProtectedMask != NULL) {

+    mProtectedModeMask = *ProtectedMask;

+  }

+

+  if (ProtectedEdgeLevel != NULL) {

+    mProtectedModeEdgeLevel = *ProtectedEdgeLevel;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets the mode of the PICs.

+

+  @param[in]  This       Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Mode       16-bit real or 32-bit protected mode.

+  @param[in]  Mask       The value with which to set the interrupt mask.

+  @param[in]  EdgeLevel  The value with which to set the edge/level mask.

+

+  @retval  EFI_SUCCESS            The mode was set successfully.

+  @retval  EFI_INVALID_PARAMETER  The mode was not set.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetMode (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_MODE             Mode,

+  IN UINT16                    *Mask, OPTIONAL

+  IN UINT16                    *EdgeLevel OPTIONAL

+  )

+{

+  if (Mode == mMode) {

+    return EFI_SUCCESS;

+  }

+

+  if (Mode == Efi8259LegacyMode) {

+    //

+    // In Efi8259ProtectedMode, mask and edge/level trigger registers should

+    // be changed through this protocol, so we can track them in the

+    // corresponding module variables.

+    //

+    Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);

+

+    if (Mask != NULL) {

+      //

+      // Update the Mask for the new mode

+      //

+      mLegacyModeMask = *Mask;

+    }

+

+    if (EdgeLevel != NULL) {

+      //

+      // Update the Edge/Level triggered mask for the new mode

+      //

+      mLegacyModeEdgeLevel = *EdgeLevel;

+    }

+

+    mMode = Mode;

+

+    //

+    // Write new legacy mode mask/trigger level

+    //

+    Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);

+

+    return EFI_SUCCESS;

+  }

+

+  if (Mode == Efi8259ProtectedMode) {

+    //

+    // Save the legacy mode mask/trigger level

+    //

+    Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);

+    //

+    // Always force Timer to be enabled after return from 16-bit code.

+    // This always insures that on next entry, timer is counting.

+    //

+    mLegacyModeMask &= 0xFFFE;

+

+    if (Mask != NULL) {

+      //

+      // Update the Mask for the new mode

+      //

+      mProtectedModeMask = *Mask;

+    }

+

+    if (EdgeLevel != NULL) {

+      //

+      // Update the Edge/Level triggered mask for the new mode

+      //

+      mProtectedModeEdgeLevel = *EdgeLevel;

+    }

+

+    mMode = Mode;

+

+    //

+    // Write new protected mode mask/trigger level

+    //

+    Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  Translates the IRQ into a vector.

+

+  @param[in]   This    Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]   Irq     IRQ0-IRQ15.

+  @param[out]  Vector  The vector that is assigned to the IRQ.

+

+  @retval  EFI_SUCCESS            The Vector that matches Irq was returned.

+  @retval  EFI_INVALID_PARAMETER  Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetVector (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  IN  EFI_8259_IRQ              Irq,

+  OUT UINT8                     *Vector

+  )

+{

+  if ((UINT32)Irq > Efi8259Irq15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Irq <= Efi8259Irq7) {

+    *Vector = (UINT8) (mMasterBase + Irq);

+  } else {

+    *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Enables the specified IRQ.

+

+  @param[in]  This            Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq             IRQ0-IRQ15.

+  @param[in]  LevelTriggered  0 = Edge triggered; 1 = Level triggered.

+

+  @retval  EFI_SUCCESS            The Irq was enabled on the 8259 PIC.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259EnableIrq (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_IRQ              Irq,

+  IN BOOLEAN                   LevelTriggered

+  )

+{

+  if ((UINT32)Irq > Efi8259Irq15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));

+  if (LevelTriggered) {

+    mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));

+  } else {

+    mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));

+  }

+

+  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Disables the specified IRQ.

+

+  @param[in]  This  Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq   IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS            The Irq was disabled on the 8259 PIC.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259DisableIrq (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_IRQ              Irq

+  )

+{

+  if ((UINT32)Irq > Efi8259Irq15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));

+

+  mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));

+

+  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Reads the PCI configuration space to get the interrupt number that is assigned to the card.

+

+  @param[in]   This       Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]   PciHandle  PCI function for which to return the vector.

+  @param[out]  Vector     IRQ number that corresponds to the interrupt line.

+

+  @retval  EFI_SUCCESS  The interrupt line value was read successfully.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetInterruptLine (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  IN  EFI_HANDLE                PciHandle,

+  OUT UINT8                     *Vector

+  )

+{

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  UINT8               InterruptLine;

+  EFI_STATUS          Status;

+

+  Status = gBS->HandleProtocol (

+                  PciHandle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  PciIo->Pci.Read (

+               PciIo,

+               EfiPciIoWidthUint8,

+               PCI_INT_LINE_OFFSET,

+               1,

+               &InterruptLine

+               );

+  //

+  // Interrupt line is same location for standard PCI cards, standard

+  // bridge and CardBus bridge.

+  //

+  *Vector = InterruptLine;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Issues the End of Interrupt (EOI) commands to PICs.

+

+  @param[in]  This  Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq   The interrupt for which to issue the EOI command.

+

+  @retval  EFI_SUCCESS            The EOI command was issued.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259EndOfInterrupt (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_IRQ              Irq

+  )

+{

+  if ((UINT32)Irq > Efi8259Irq15) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Irq >= Efi8259Irq8) {

+    IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);

+  }

+

+  IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Driver Entry point.

+

+  @param[in]  ImageHandle  ImageHandle of the loaded driver.

+  @param[in]  SystemTable  Pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS  One or more of the drivers returned a success code.

+  @retval  !EFI_SUCCESS  Error installing Legacy 8259 Protocol.

+

+**/

+EFI_STATUS

+EFIAPI

+Install8259 (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS   Status;

+  EFI_8259_IRQ Irq;

+

+  //

+  // Initialze mask values from PCDs

+  //

+  mLegacyModeMask      = PcdGet16 (Pcd8259LegacyModeMask);

+  mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);

+

+  //

+  // Clear all pending interrupt

+  //

+  for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {

+    Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);

+  }

+

+  //

+  // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70

+  //

+  Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);

+

+  //

+  // Set all 8259 interrupts to edge triggered and disabled

+  //

+  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

+

+  //

+  // Install 8259 Protocol onto a new handle

+  //

+  Status = gBS->InstallProtocolInterface (

+                  &m8259Handle,

+                  &gEfiLegacy8259ProtocolGuid,

+                  EFI_NATIVE_INTERFACE,

+                  &mInterrupt8259

+                  );

+  return Status;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
new file mode 100644
index 0000000..0d4c1e8
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
@@ -0,0 +1,226 @@
+/** @file

+  Driver implementing the Tiano Legacy 8259 Protocol

+

+Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+#ifndef _8259_H__

+#define _8259_H__

+

+#include <FrameworkDxe.h>

+

+#include <Protocol/Legacy8259.h>

+#include <Protocol/PciIo.h>

+

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PcdLib.h>

+

+#include <IndustryStandard/Pci.h>

+

+// 8259 Hardware definitions

+

+#define LEGACY_MODE_BASE_VECTOR_MASTER                    0x08

+#define LEGACY_MODE_BASE_VECTOR_SLAVE                     0x70

+

+#define PROTECTED_MODE_BASE_VECTOR_MASTER                 0x68

+#define PROTECTED_MODE_BASE_VECTOR_SLAVE                  0x70

+

+#define LEGACY_8259_CONTROL_REGISTER_MASTER               0x20

+#define LEGACY_8259_MASK_REGISTER_MASTER                  0x21

+#define LEGACY_8259_CONTROL_REGISTER_SLAVE                0xA0

+#define LEGACY_8259_MASK_REGISTER_SLAVE                   0xA1

+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER  0x4D0

+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE   0x4D1

+

+#define LEGACY_8259_EOI                                   0x20

+

+// Protocol Function Prototypes

+

+/**

+  Sets the base address for the 8259 master and slave PICs.

+

+  @param[in]  This        Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  MasterBase  Interrupt vectors for IRQ0-IRQ7.

+  @param[in]  SlaveBase   Interrupt vectors for IRQ8-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while writing to the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetVectorBase (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN UINT8                     MasterBase,

+  IN UINT8                     SlaveBase

+  );

+

+/**

+  Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.

+

+  @param[in]   This                Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[out]  LegacyMask          16-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[out]  LegacyEdgeLevel     16-bit mode edge/level mask for IRQ-IRQ15.

+  @param[out]  ProtectedMask       32-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[out]  ProtectedEdgeLevel  32-bit mode edge/level mask for IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while reading the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetMask (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  OUT UINT16                    *LegacyMask, OPTIONAL

+  OUT UINT16                    *LegacyEdgeLevel, OPTIONAL

+  OUT UINT16                    *ProtectedMask, OPTIONAL

+  OUT UINT16                    *ProtectedEdgeLevel OPTIONAL

+  );

+

+/**

+  Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.

+

+  @param[in]  This                Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  LegacyMask          16-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[in]  LegacyEdgeLevel     16-bit mode edge/level mask for IRQ-IRQ15.

+  @param[in]  ProtectedMask       32-bit mode interrupt mask for IRQ0-IRQ15.

+  @param[in]  ProtectedEdgeLevel  32-bit mode edge/level mask for IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS       The 8259 PIC was programmed successfully.

+  @retval  EFI_DEVICE_ERROR  There was an error while writing the 8259 PIC.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetMask (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN UINT16                    *LegacyMask, OPTIONAL

+  IN UINT16                    *LegacyEdgeLevel, OPTIONAL

+  IN UINT16                    *ProtectedMask, OPTIONAL

+  IN UINT16                    *ProtectedEdgeLevel OPTIONAL

+  );

+

+/**

+  Sets the mode of the PICs.

+

+  @param[in]  This       Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Mode       16-bit real or 32-bit protected mode.

+  @param[in]  Mask       The value with which to set the interrupt mask.

+  @param[in]  EdgeLevel  The value with which to set the edge/level mask.

+

+  @retval  EFI_SUCCESS            The mode was set successfully.

+  @retval  EFI_INVALID_PARAMETER  The mode was not set.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259SetMode (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_MODE             Mode,

+  IN UINT16                    *Mask, OPTIONAL

+  IN UINT16                    *EdgeLevel OPTIONAL

+  );

+

+/**

+  Translates the IRQ into a vector.

+

+  @param[in]   This    Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]   Irq     IRQ0-IRQ15.

+  @param[out]  Vector  The vector that is assigned to the IRQ.

+

+  @retval  EFI_SUCCESS            The Vector that matches Irq was returned.

+  @retval  EFI_INVALID_PARAMETER  Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetVector (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  IN  EFI_8259_IRQ              Irq,

+  OUT UINT8                     *Vector

+  );

+

+/**

+  Enables the specified IRQ.

+

+  @param[in]  This            Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq             IRQ0-IRQ15.

+  @param[in]  LevelTriggered  0 = Edge triggered; 1 = Level triggered.

+

+  @retval  EFI_SUCCESS            The Irq was enabled on the 8259 PIC.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259EnableIrq (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_IRQ              Irq,

+  IN BOOLEAN                   LevelTriggered

+  );

+

+/**

+  Disables the specified IRQ.

+

+  @param[in]  This  Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq   IRQ0-IRQ15.

+

+  @retval  EFI_SUCCESS            The Irq was disabled on the 8259 PIC.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259DisableIrq (

+  IN EFI_LEGACY_8259_PROTOCOL  *This,

+  IN EFI_8259_IRQ              Irq

+  );

+

+/**

+  Reads the PCI configuration space to get the interrupt number that is assigned to the card.

+

+  @param[in]   This       Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]   PciHandle  PCI function for which to return the vector.

+  @param[out]  Vector     IRQ number that corresponds to the interrupt line.

+

+  @retval  EFI_SUCCESS  The interrupt line value was read successfully.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259GetInterruptLine (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  IN  EFI_HANDLE                PciHandle,

+  OUT UINT8                     *Vector

+  );

+

+/**

+  Issues the End of Interrupt (EOI) commands to PICs.

+

+  @param[in]  This  Indicates the EFI_LEGACY_8259_PROTOCOL instance.

+  @param[in]  Irq   The interrupt for which to issue the EOI command.

+

+  @retval  EFI_SUCCESS            The EOI command was issued.

+  @retval  EFI_INVALID_PARAMETER  The Irq is not valid.

+

+**/

+EFI_STATUS

+EFIAPI

+Interrupt8259EndOfInterrupt (

+  IN  EFI_LEGACY_8259_PROTOCOL  *This,

+  IN  EFI_8259_IRQ              Irq

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
new file mode 100644
index 0000000..09bcbbb
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
@@ -0,0 +1,52 @@
+## @file

+# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.

+#

+# Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>

+# 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.             

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Legacy8259

+  MODULE_UNI_FILE                = Legacy8259.uni

+  FILE_GUID                      = 79CA4208-BBA1-4a9a-8456-E1E66A81484E

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = Install8259

+

+[Sources]

+  8259.c

+  8259.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+  IntelFrameworkPkg/IntelFrameworkPkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+  

+[LibraryClasses]

+  UefiBootServicesTableLib

+  DebugLib

+  UefiDriverEntryPoint

+  IoLib

+  PcdLib

+  

+[Protocols]

+  gEfiLegacy8259ProtocolGuid                    ## PRODUCES

+  gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMES

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask      ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES

+  

+[Depex]

+  TRUE

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  Legacy8259Extra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
new file mode 100644
index 0000000..812f5e4
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
new file mode 100644
index 0000000..ad5e721
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/ComponentName.c b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/ComponentName.c
new file mode 100644
index 0000000..6e9d707
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/ComponentName.c
@@ -0,0 +1,177 @@
+/** @file

+  This portion is to register the IDE Controller Driver name:

+  "IDE Controller Init Driver"

+

+  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include "IdeController.h"

+

+//

+/// EFI Component Name Protocol

+///

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gIdeControllerComponentName = {

+  IdeControllerComponentNameGetDriverName,

+  IdeControllerComponentNameGetControllerName,

+  "eng"

+};

+

+//

+/// EFI Component Name 2 Protocol

+///

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIdeControllerComponentName2 = {

+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IdeControllerComponentNameGetDriverName,

+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IdeControllerComponentNameGetControllerName,

+  "en"

+};

+

+//

+/// Driver Name Strings

+///

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIdeControllerDriverNameTable[] = {

+  {

+    "eng;en",

+    (CHAR16 *)L"IDE Controller Init Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+///

+/// Controller Name Strings

+///

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIdeControllerControllerNameTable[] = {

+  {

+    "eng;en",

+    (CHAR16 *)L"PCAT IDE Controller"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+/**

+  Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param Language       A pointer to a three character ISO 639-2 language identifier.

+                        This is the language of the driver name that that the caller

+                        is requesting, and it must match one of the languages specified

+                        in SupportedLanguages.  The number of languages supported by a

+                        driver is up to the driver writer.

+  @param DriverName     A pointer to the Unicode string to return.  This Unicode string

+                        is the name of the driver specified by This in the language

+                        specified by Language.

+  

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by This

+                                and the language specified by Language was returned

+                                in DriverName.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+{

+  return LookupUnicodeString2 (

+           Language,

+           This->SupportedLanguages,

+           mIdeControllerDriverNameTable,

+           DriverName,

+           (BOOLEAN)(This == &gIdeControllerComponentName)

+           );

+}

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by an EFI Driver.  

+

+  @param This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param ControllerHandle       The handle of a controller that the driver specified by

+                                This is managing.  This handle specifies the controller

+                                whose name is to be returned.

+  @param ChildHandle OPTIONAL   The handle of the child controller to retrieve the name

+                                of.  This is an optional parameter that may be NULL.  It

+                                will be NULL for device drivers.  It will also be NULL

+                                for a bus drivers that wish to retrieve the name of the

+                                bus controller.  It will not be NULL for a bus driver

+                                that wishes to retrieve the name of a child controller.

+  @param Language               A pointer to a three character ISO 639-2 language

+                                identifier.  This is the language of the controller name

+                                that that the caller is requesting, and it must match one

+                                of the languages specified in SupportedLanguages.  The

+                                number of languages supported by a driver is up to the

+                                driver writer.

+  @param ControllerName         A pointer to the Unicode string to return.  This Unicode

+                                string is the name of the controller specified by

+                                ControllerHandle and ChildHandle in the language

+                                specified by Language from the point of view of the

+                                driver specified by This.

+  

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in the

+                                language specified by Language for the driver

+                                specified by This was returned in DriverName.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+{

+  EFI_STATUS            Status;

+

+  //

+  // Make sure this driver is currently managing ControllHandle

+  //

+  Status = EfiTestManagedDevice (

+             ControllerHandle,

+             gIdeControllerDriverBinding.DriverBindingHandle,

+             &gEfiPciIoProtocolGuid

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return LookupUnicodeString2 (

+          Language,

+          This->SupportedLanguages,

+          mIdeControllerControllerNameTable,

+          ControllerName,

+          (BOOLEAN)(This == &gIdeControllerComponentName)

+          );

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.c b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.c
new file mode 100644
index 0000000..21b8e26
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.c
@@ -0,0 +1,619 @@
+/** @file

+  This driver module produces IDE_CONTROLLER_INIT protocol and will be used by

+  IDE Bus driver to support platform dependent timing information. This driver

+  is responsible for early initialization of IDE controller.

+

+  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include "IdeController.h"

+

+///

+///  EFI_DRIVER_BINDING_PROTOCOL instance

+///

+EFI_DRIVER_BINDING_PROTOCOL gIdeControllerDriverBinding = {

+  IdeControllerSupported,

+  IdeControllerStart,

+  IdeControllerStop,

+  0xa,

+  NULL,

+  NULL

+};

+

+///

+///  EFI_IDE_CONTROLLER_PROVATE_DATA Template

+///

+EFI_IDE_CONTROLLER_INIT_PROTOCOL  gEfiIdeControllerInit = {

+  IdeInitGetChannelInfo,

+  IdeInitNotifyPhase,

+  IdeInitSubmitData,

+  IdeInitDisqualifyMode,

+  IdeInitCalculateMode,

+  IdeInitSetTiming,

+  ICH_IDE_ENUMER_ALL,

+  ICH_IDE_MAX_CHANNEL

+};

+

+///

+///  EFI_ATA_COLLECTIVE_MODE Template

+///

+EFI_ATA_COLLECTIVE_MODE  gEfiAtaCollectiveModeTemplate = {

+  {

+    TRUE,                   ///< PioMode.Valid

+    0                       ///< PioMode.Mode

+  },

+  {

+    TRUE,                   ///< SingleWordDmaMode.Valid

+    0

+  },

+  {

+    FALSE,                  ///< MultiWordDmaMode.Valid

+    0

+  },

+  {

+    TRUE,                   ///< UdmaMode.Valid

+    0                       ///< UdmaMode.Mode

+  }

+};

+

+/**

+  Chipset Ide Driver EntryPoint function. It follows the standard EFI driver model.

+  It's called by StartImage() of DXE Core.

+

+  @param ImageHandle    While the driver image loaded be the ImageLoader(),

+                        an image handle is assigned to this driver binary,

+                        all activities of the driver is tied to this ImageHandle

+  @param SystemTable    A pointer to the system table, for all BS(Boo Services) and

+                        RT(Runtime Services)

+

+  @return EFI_STATUS    Status of  EfiLibInstallDriverBindingComponentName2().

+**/

+EFI_STATUS

+EFIAPI

+InitializeIdeControllerDriver (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Install driver model protocol(s).

+  //

+  Status = EfiLibInstallDriverBindingComponentName2 (

+             ImageHandle,

+             SystemTable,

+             &gIdeControllerDriverBinding,

+             ImageHandle,

+             &gIdeControllerComponentName,

+             &gIdeControllerComponentName2

+             );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  Register Driver Binding protocol for this driver.

+

+  @param This                   A pointer points to the Binding Protocol instance

+  @param Controller             The handle of controller to be tested.

+  @param RemainingDevicePath    A pointer to the device path. Ignored by device

+                                driver but used by bus driver

+

+  @retval EFI_SUCCESS           Driver loaded.

+  @retval !EFI_SUCESS           Driver not loaded.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL *This,

+  IN EFI_HANDLE                  Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath

+  )

+{

+  EFI_STATUS                Status;

+  EFI_PCI_IO_PROTOCOL       *PciIo;

+  UINT8                     PciClass;

+  UINT8                     PciSubClass;

+

+  //

+  // Attempt to Open PCI I/O Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Now further check the PCI header: Base class (offset 0x0B) and

+  // Sub Class (offset 0x0A). This controller should be an Ide controller

+  //

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint8,

+                        PCI_CLASSCODE_OFFSET + 2,

+                        1,

+                        &PciClass

+                        );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint8,

+                        PCI_CLASSCODE_OFFSET + 1,

+                        1,

+                        &PciSubClass

+                        );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Examine Ide PCI Configuration table fields

+  //

+  if ((PciClass != PCI_CLASS_MASS_STORAGE) || (PciSubClass != PCI_CLASS_MASS_STORAGE_IDE)) {

+    Status = EFI_UNSUPPORTED;

+  }

+

+Done:

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+/**

+  This routine is called right after the .Supported() called and return

+  EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols

+  are closed.

+

+  @param This                   A pointer points to the Binding Protocol instance

+  @param Controller             The handle of controller to be tested. Parameter

+                                passed by the caller

+  @param RemainingDevicePath    A pointer to the device path. Should be ignored by

+                                device driver

+

+  @return EFI_STATUS            Status of InstallMultipleProtocolInterfaces()

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+{

+  EFI_STATUS           Status;

+  EFI_PCI_IO_PROTOCOL  *PciIo;

+

+  //

+  // Now test and open the EfiPciIoProtocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  //

+  // Status == EFI_SUCCESS - A normal execution flow, SUCCESS and the program proceeds.

+  // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates

+  //           that the protocol has been opened and should be treated as a

+  //           normal condition and the program proceeds. The Protocol will not

+  //           opened 'again' by this call.

+  // Status != ALREADY_STARTED - Error status, terminate program execution

+  //

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Install IDE_CONTROLLER_INIT protocol

+  //

+  return gBS->InstallMultipleProtocolInterfaces (

+                &Controller,

+                &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,

+                NULL

+                );

+}

+

+/**

+  Stop this driver on Controller Handle.

+

+  @param This               Protocol instance pointer.

+  @param Controller         Handle of device to stop driver on

+  @param NumberOfChildren   Not used

+  @param ChildHandleBuffer  Not used

+

+  @retval EFI_SUCESS        This driver is removed DeviceHandle

+  @retval !EFI_SUCCESS      This driver was not removed from this device

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,

+  IN  EFI_HANDLE                      Controller,

+  IN  UINTN                           NumberOfChildren,

+  IN  EFI_HANDLE                      *ChildHandleBuffer

+  )

+{

+  EFI_STATUS                        Status;

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeControllerInit;

+

+  //

+  // Open the produced protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiIdeControllerInitProtocolGuid,

+                  (VOID **) &IdeControllerInit,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+     return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Make sure the protocol was produced by this driver

+  //

+  if (IdeControllerInit != &gEfiIdeControllerInit) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Uninstall the IDE Controller Init Protocol

+  //

+  Status = gBS->UninstallMultipleProtocolInterfaces (

+                  Controller,

+                  &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Close protocols opened by Ide controller driver

+  //

+  return gBS->CloseProtocol (

+                Controller,

+                &gEfiPciIoProtocolGuid,

+                This->DriverBindingHandle,

+                Controller

+                );

+}

+

+//

+// Interface functions of IDE_CONTROLLER_INIT protocol

+//

+/**

+  Returns the information about the specified IDE channel.

+  

+  This function can be used to obtain information about a particular IDE channel.

+  The driver entity uses this information during the enumeration process. 

+  

+  If Enabled is set to FALSE, the driver entity will not scan the channel. Note 

+  that it will not prevent an operating system driver from scanning the channel.

+  

+  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA 

+  controllers, this value will always be 1. SATA configurations can contain SATA 

+  port multipliers. SATA port multipliers behave like SATA bridges and can support

+  up to 16 devices on the other side. If a SATA port out of the IDE controller 

+  is connected to a port multiplier, MaxDevices will be set to the number of SATA 

+  devices that the port multiplier supports. Because today's port multipliers 

+  support up to fifteen SATA devices, this number can be as large as fifteen. The IDE  

+  bus driver is required to scan for the presence of port multipliers behind an SATA 

+  controller and enumerate up to MaxDevices number of devices behind the port 

+  multiplier.    

+  

+  In this context, the devices behind a port multiplier constitute a channel.  

+  

+  @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in]  Channel      Zero-based channel number.

+  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels 

+                           are not scanned to see if any devices are present.

+  @param[out] MaxDevices   The maximum number of IDE devices that the bus driver

+                           can expect on this channel.  For the ATA/ATAPI 

+                           specification, version 6, this number will either be 

+                           one or two. For Serial ATA (SATA) configurations with a 

+                           port multiplier, this number can be as large as fifteen.

+

+  @retval EFI_SUCCESS             Information was returned without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitGetChannelInfo (

+  IN   EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN   UINT8                            Channel,

+  OUT  BOOLEAN                          *Enabled,

+  OUT  UINT8                            *MaxDevices

+  )

+{

+  //

+  // Channel number (0 based, either 0 or 1)

+  //

+  if (Channel < ICH_IDE_MAX_CHANNEL) {

+    *Enabled    = TRUE;

+    *MaxDevices = ICH_IDE_MAX_DEVICES;

+    return EFI_SUCCESS;

+  }

+

+  *Enabled = FALSE;

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+  The notifications from the driver entity that it is about to enter a certain

+  phase of the IDE channel enumeration process.

+  

+  This function can be used to notify the IDE controller driver to perform 

+  specific actions, including any chipset-specific initialization, so that the 

+  chipset is ready to enter the next phase. Seven notification points are defined 

+  at this time. 

+  

+  More synchronization points may be added as required in the future.  

+

+  @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Phase     The phase during enumeration.

+  @param[in] Channel   Zero-based channel number.

+

+  @retval EFI_SUCCESS             The notification was accepted without any errors.

+  @retval EFI_UNSUPPORTED         Phase is not supported.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_NOT_READY           This phase cannot be entered at this time; for 

+                                  example, an attempt was made to enter a Phase 

+                                  without having entered one or more previous 

+                                  Phase.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitNotifyPhase (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,

+  IN  EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,

+  IN  UINT8                              Channel

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  Submits the device information to the IDE controller driver.

+

+  This function is used by the driver entity to pass detailed information about 

+  a particular device to the IDE controller driver. The driver entity obtains 

+  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData

+  is the pointer to the response data buffer. The IdentifyData buffer is owned 

+  by the driver entity, and the IDE controller driver must make a local copy 

+  of the entire buffer or parts of the buffer as needed. The original IdentifyData 

+  buffer pointer may not be valid when

+  

+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or

+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.

+    

+  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to 

+  compute the optimum mode for the device. These fields are not limited to the 

+  timing information. For example, an implementation of the IDE controller driver 

+  may examine the vendor and type/mode field to match known bad drives.  

+  

+  The driver entity may submit drive information in any order, as long as it 

+  submits information for all the devices belonging to the enumeration group 

+  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device

+  in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()

+  should be called with IdentifyData set to NULL.  The IDE controller driver may 

+  not have any other mechanism to know whether a device is present or not. Therefore, 

+  setting IdentifyData to NULL does not constitute an error condition. 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a 

+  given (Channel, Device) pair.  

+    

+  @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel        Zero-based channel number.

+  @param[in] Device         Zero-based device number on the Channel.

+  @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.

+

+  @retval EFI_SUCCESS             The information was accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitSubmitData (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL    *This,

+  IN  UINT8                               Channel,

+  IN  UINT8                               Device,

+  IN  EFI_IDENTIFY_DATA                   *IdentifyData

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  Disqualifies specific modes for an IDE device.

+

+  This function allows the driver entity or other drivers (such as platform 

+  drivers) to reject certain timing modes and request the IDE controller driver

+  to recalculate modes. This function allows the driver entity and the IDE 

+  controller driver to negotiate the timings on a per-device basis. This function 

+  is useful in the case of drives that lie about their capabilities. An example 

+  is when the IDE device fails to accept the timing modes that are calculated 

+  by the IDE controller driver based on the response to the Identify Drive command.

+

+  If the driver entity does not want to limit the ATA timing modes and leave that 

+  decision to the IDE controller driver, it can either not call this function for 

+  the given device or call this function and set the Valid flag to FALSE for all 

+  modes that are listed in EFI_ATA_COLLECTIVE_MODE.

+  

+  The driver entity may disqualify modes for a device in any order and any number 

+  of times.

+  

+  This function can be called multiple times to invalidate multiple modes of the 

+  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI 

+  specification for more information on PIO modes.  

+  

+  For Serial ATA (SATA) controllers, this member function can be used to disqualify

+  a higher transfer rate mode on a given channel. For example, a platform driver

+  may inform the IDE controller driver to not use second-generation (Gen2) speeds 

+  for a certain SATA drive.

+  

+  @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel    The zero-based channel number.

+  @param[in] Device     The zero-based device number on the Channel.

+  @param[in] BadModes   The modes that the device does not support and that

+                        should be disqualified.

+

+  @retval EFI_SUCCESS             The modes were accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.

+                                

+**/

+EFI_STATUS

+EFIAPI

+IdeInitDisqualifyMode (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL    *This,

+  IN  UINT8                               Channel,

+  IN  UINT8                               Device,

+  IN  EFI_ATA_COLLECTIVE_MODE             *BadModes

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  Returns the information about the optimum modes for the specified IDE device.

+

+  This function is used by the driver entity to obtain the optimum ATA modes for

+  a specific device.  The IDE controller driver takes into account the following 

+  while calculating the mode:

+    - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()

+    - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()

+

+  The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 

+  for all the devices that belong to an enumeration group before calling 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.  

+  

+  The IDE controller driver will use controller- and possibly platform-specific 

+  algorithms to arrive at SupportedModes.  The IDE controller may base its 

+  decision on user preferences and other considerations as well. This function 

+  may be called multiple times because the driver entity may renegotiate the mode 

+  with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().

+    

+  The driver entity may collect timing information for various devices in any 

+  order. The driver entity is responsible for making sure that all the dependencies

+  are satisfied. For example, the SupportedModes information for device A that 

+  was previously returned may become stale after a call to 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.

+  

+  The buffer SupportedModes is allocated by the callee because the caller does 

+  not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE 

+  is defined in a way that allows for future extensibility and can be of variable 

+  length. This memory pool should be deallocated by the caller when it is no 

+  longer necessary.  

+  

+  The IDE controller driver for a Serial ATA (SATA) controller can use this 

+  member function to force a lower speed (first-generation [Gen1] speeds on a 

+  second-generation [Gen2]-capable hardware).  The IDE controller driver can 

+  also allow the driver entity to stay with the speed that has been negotiated 

+  by the physical layer.

+  

+  @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in]  Channel          A zero-based channel number.

+  @param[in]  Device           A zero-based device number on the Channel.

+  @param[out] SupportedModes   The optimum modes for the device.

+

+  @retval EFI_SUCCESS             SupportedModes was returned.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid. 

+  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.

+  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of 

+                                  data.  This error may happen if 

+                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 

+                                  and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData() 

+                                  were not called for at least one drive in the 

+                                  same enumeration group.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitCalculateMode (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL       *This,

+  IN  UINT8                                  Channel,

+  IN  UINT8                                  Device,

+  OUT EFI_ATA_COLLECTIVE_MODE                **SupportedModes

+  )

+{

+  if (Channel >= ICH_IDE_MAX_CHANNEL || Device >= ICH_IDE_MAX_DEVICES) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *SupportedModes = AllocateCopyPool (sizeof (EFI_ATA_COLLECTIVE_MODE), &gEfiAtaCollectiveModeTemplate);

+  if (*SupportedModes == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Commands the IDE controller driver to program the IDE controller hardware

+  so that the specified device can operate at the specified mode.

+

+  This function is used by the driver entity to instruct the IDE controller 

+  driver to program the IDE controller hardware to the specified modes. This 

+  function can be called only once for a particular device. For a Serial ATA 

+  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-

+  specific programming may be required.

+

+  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel   Zero-based channel number.

+  @param[in] Device    Zero-based device number on the Channel.

+  @param[in] Modes     The modes to set.

+

+  @retval EFI_SUCCESS             The command was accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.

+  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.

+                                  The driver entity should not use this device.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitSetTiming (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL    *This,

+  IN  UINT8                               Channel,

+  IN  UINT8                               Device,

+  IN  EFI_ATA_COLLECTIVE_MODE             *Modes

+  )

+{

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.h b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.h
new file mode 100644
index 0000000..3ecde08
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.h
@@ -0,0 +1,478 @@
+/** @file

+  Header file for IDE controller driver.

+

+  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef _IDE_CONTROLLER_H_

+#define _IDE_CONTROLLER_H_

+

+#include <Uefi.h>

+#include <Protocol/ComponentName.h>

+#include <Protocol/DriverBinding.h>

+#include <Protocol/PciIo.h>

+#include <Protocol/IdeControllerInit.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <IndustryStandard/Pci.h>

+

+//

+// Global Variables definitions

+//

+extern EFI_DRIVER_BINDING_PROTOCOL  gIdeControllerDriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL  gIdeControllerComponentName;

+extern EFI_COMPONENT_NAME2_PROTOCOL gIdeControllerComponentName2;

+

+///

+/// Supports 2 channel max

+///

+#define ICH_IDE_MAX_CHANNEL 0x02

+

+///

+/// Supports 2 devices max

+///

+#define ICH_IDE_MAX_DEVICES 0x02

+#define ICH_IDE_ENUMER_ALL  FALSE

+

+//

+// Driver binding functions declaration

+//

+/**

+  Register Driver Binding protocol for this driver.

+

+  @param This                   A pointer points to the Binding Protocol instance

+  @param Controller             The handle of controller to be tested.

+  @param RemainingDevicePath    A pointer to the device path. Ignored by device

+                                driver but used by bus driver

+

+  @retval EFI_SUCCESS           Driver loaded.

+  @retval !EFI_SUCESS           Driver not loaded.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL       *This,

+  IN EFI_HANDLE                        Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath

+  )

+;

+

+/**

+  This routine is called right after the .Supported() called and return

+  EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols

+  are closed.

+

+  @param This                   A pointer points to the Binding Protocol instance

+  @param Controller             The handle of controller to be tested. Parameter

+                                passed by the caller

+  @param RemainingDevicePath    A pointer to the device path. Should be ignored by

+                                device driver

+

+  @return EFI_STATUS            Status of InstallMultipleProtocolInterfaces()

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL        *This,

+  IN EFI_HANDLE                         Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath

+  )

+;

+

+/**

+  Stop this driver on Controller Handle.

+

+  @param This               Protocol instance pointer.

+  @param Controller         Handle of device to stop driver on

+  @param NumberOfChildren   Not used

+  @param ChildHandleBuffer  Not used

+

+  @retval EFI_SUCESS        This driver is removed DeviceHandle

+  @retval !EFI_SUCCESS      This driver was not removed from this device

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL       *This,

+  IN  EFI_HANDLE                        Controller,

+  IN  UINTN                             NumberOfChildren,

+  IN  EFI_HANDLE                        *ChildHandleBuffer

+  )

+;

+

+//

+// IDE controller init functions declaration

+//

+/**

+  Returns the information about the specified IDE channel.

+  

+  This function can be used to obtain information about a particular IDE channel.

+  The driver entity uses this information during the enumeration process. 

+  

+  If Enabled is set to FALSE, the driver entity will not scan the channel. Note 

+  that it will not prevent an operating system driver from scanning the channel.

+  

+  For most of today's controllers, MaxDevices will either be 1 or 2. For SATA 

+  controllers, this value will always be 1. SATA configurations can contain SATA 

+  port multipliers. SATA port multipliers behave like SATA bridges and can support

+  up to 16 devices on the other side. If a SATA port out of the IDE controller 

+  is connected to a port multiplier, MaxDevices will be set to the number of SATA 

+  devices that the port multiplier supports. Because today's port multipliers 

+  support up to fifteen SATA devices, this number can be as large as fifteen. The IDE  

+  bus driver is required to scan for the presence of port multipliers behind an SATA 

+  controller and enumerate up to MaxDevices number of devices behind the port 

+  multiplier.    

+  

+  In this context, the devices behind a port multiplier constitute a channel.  

+  

+  @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in]  Channel      Zero-based channel number.

+  @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels 

+                           are not scanned to see if any devices are present.

+  @param[out] MaxDevices   The maximum number of IDE devices that the bus driver

+                           can expect on this channel.  For the ATA/ATAPI 

+                           specification, version 6, this number will either be 

+                           one or two. For Serial ATA (SATA) configurations with a 

+                           port multiplier, this number can be as large as fifteen.

+

+  @retval EFI_SUCCESS             Information was returned without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitGetChannelInfo (

+  IN   EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,

+  IN   UINT8                            Channel,

+  OUT  BOOLEAN                          *Enabled,

+  OUT  UINT8                            *MaxDevices

+  )

+;

+

+/**

+  The notifications from the driver entity that it is about to enter a certain

+  phase of the IDE channel enumeration process.

+  

+  This function can be used to notify the IDE controller driver to perform 

+  specific actions, including any chipset-specific initialization, so that the 

+  chipset is ready to enter the next phase. Seven notification points are defined 

+  at this time. 

+  

+  More synchronization points may be added as required in the future.  

+

+  @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Phase     The phase during enumeration.

+  @param[in] Channel   Zero-based channel number.

+

+  @retval EFI_SUCCESS             The notification was accepted without any errors.

+  @retval EFI_UNSUPPORTED         Phase is not supported.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_NOT_READY           This phase cannot be entered at this time; for 

+                                  example, an attempt was made to enter a Phase 

+                                  without having entered one or more previous 

+                                  Phase.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitNotifyPhase (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN  EFI_IDE_CONTROLLER_ENUM_PHASE     Phase,

+  IN  UINT8                             Channel

+  )

+;

+

+/**

+  Submits the device information to the IDE controller driver.

+

+  This function is used by the driver entity to pass detailed information about 

+  a particular device to the IDE controller driver. The driver entity obtains 

+  this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData

+  is the pointer to the response data buffer. The IdentifyData buffer is owned 

+  by the driver entity, and the IDE controller driver must make a local copy 

+  of the entire buffer or parts of the buffer as needed. The original IdentifyData 

+  buffer pointer may not be valid when

+  

+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or

+    - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.

+    

+  The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to 

+  compute the optimum mode for the device. These fields are not limited to the 

+  timing information. For example, an implementation of the IDE controller driver 

+  may examine the vendor and type/mode field to match known bad drives.  

+  

+  The driver entity may submit drive information in any order, as long as it 

+  submits information for all the devices belonging to the enumeration group 

+  before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device

+  in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()

+  should be called with IdentifyData set to NULL.  The IDE controller driver may 

+  not have any other mechanism to know whether a device is present or not. Therefore, 

+  setting IdentifyData to NULL does not constitute an error condition. 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a 

+  given (Channel, Device) pair.  

+    

+  @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel        Zero-based channel number.

+  @param[in] Device         Zero-based device number on the Channel.

+  @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.

+

+  @retval EFI_SUCCESS             The information was accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitSubmitData (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN  UINT8                             Channel,

+  IN  UINT8                             Device,

+  IN  EFI_IDENTIFY_DATA                 *IdentifyData

+  )

+;

+

+/**

+  Disqualifies specific modes for an IDE device.

+

+  This function allows the driver entity or other drivers (such as platform 

+  drivers) to reject certain timing modes and request the IDE controller driver

+  to recalculate modes. This function allows the driver entity and the IDE 

+  controller driver to negotiate the timings on a per-device basis. This function 

+  is useful in the case of drives that lie about their capabilities. An example 

+  is when the IDE device fails to accept the timing modes that are calculated 

+  by the IDE controller driver based on the response to the Identify Drive command.

+

+  If the driver entity does not want to limit the ATA timing modes and leave that 

+  decision to the IDE controller driver, it can either not call this function for 

+  the given device or call this function and set the Valid flag to FALSE for all 

+  modes that are listed in EFI_ATA_COLLECTIVE_MODE.

+  

+  The driver entity may disqualify modes for a device in any order and any number 

+  of times.

+  

+  This function can be called multiple times to invalidate multiple modes of the 

+  same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI 

+  specification for more information on PIO modes.  

+  

+  For Serial ATA (SATA) controllers, this member function can be used to disqualify

+  a higher transfer rate mode on a given channel. For example, a platform driver

+  may inform the IDE controller driver to not use second-generation (Gen2) speeds 

+  for a certain SATA drive.

+  

+  @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel    The zero-based channel number.

+  @param[in] Device     The zero-based device number on the Channel.

+  @param[in] BadModes   The modes that the device does not support and that

+                        should be disqualified.

+

+  @retval EFI_SUCCESS             The modes were accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+  @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.

+                                

+**/

+EFI_STATUS

+EFIAPI

+IdeInitDisqualifyMode (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN  UINT8                             Channel,

+  IN  UINT8                             Device,

+  IN  EFI_ATA_COLLECTIVE_MODE           *BadModes

+  )

+;

+

+/**

+  Returns the information about the optimum modes for the specified IDE device.

+

+  This function is used by the driver entity to obtain the optimum ATA modes for

+  a specific device.  The IDE controller driver takes into account the following 

+  while calculating the mode:

+    - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()

+    - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()

+

+  The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 

+  for all the devices that belong to an enumeration group before calling 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.  

+  

+  The IDE controller driver will use controller- and possibly platform-specific 

+  algorithms to arrive at SupportedModes.  The IDE controller may base its 

+  decision on user preferences and other considerations as well. This function 

+  may be called multiple times because the driver entity may renegotiate the mode 

+  with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().

+    

+  The driver entity may collect timing information for various devices in any 

+  order. The driver entity is responsible for making sure that all the dependencies

+  are satisfied. For example, the SupportedModes information for device A that 

+  was previously returned may become stale after a call to 

+  EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.

+  

+  The buffer SupportedModes is allocated by the callee because the caller does 

+  not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE 

+  is defined in a way that allows for future extensibility and can be of variable 

+  length. This memory pool should be deallocated by the caller when it is no 

+  longer necessary.  

+  

+  The IDE controller driver for a Serial ATA (SATA) controller can use this 

+  member function to force a lower speed (first-generation [Gen1] speeds on a 

+  second-generation [Gen2]-capable hardware).  The IDE controller driver can 

+  also allow the driver entity to stay with the speed that has been negotiated 

+  by the physical layer.

+  

+  @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in]  Channel          A zero-based channel number.

+  @param[in]  Device           A zero-based device number on the Channel.

+  @param[out] SupportedModes   The optimum modes for the device.

+

+  @retval EFI_SUCCESS             SupportedModes was returned.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid. 

+  @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.

+  @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of 

+                                  data.  This error may happen if 

+                                  EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() 

+                                  and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData() 

+                                  were not called for at least one drive in the 

+                                  same enumeration group.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitCalculateMode (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN  UINT8                             Channel,

+  IN  UINT8                             Device,

+  OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes

+  )

+;

+

+/**

+  Commands the IDE controller driver to program the IDE controller hardware

+  so that the specified device can operate at the specified mode.

+

+  This function is used by the driver entity to instruct the IDE controller 

+  driver to program the IDE controller hardware to the specified modes. This 

+  function can be called only once for a particular device. For a Serial ATA 

+  (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-

+  specific programming may be required.

+

+  @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.

+  @param[in] Channel   Zero-based channel number.

+  @param[in] Device    Zero-based device number on the Channel.

+  @param[in] Modes     The modes to set.

+

+  @retval EFI_SUCCESS             The command was accepted without any errors.

+  @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).

+  @retval EFI_INVALID_PARAMETER   Device is invalid.

+  @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.

+  @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.

+                                  The driver entity should not use this device.

+

+**/

+EFI_STATUS

+EFIAPI

+IdeInitSetTiming (

+  IN  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *This,

+  IN  UINT8                             Channel,

+  IN  UINT8                             Device,

+  IN  EFI_ATA_COLLECTIVE_MODE           *Modes

+  )

+;

+

+//

+// Forward reference declaration

+//

+/**

+  Retrieves a Unicode string that is the user readable name of the EFI Driver.

+

+  @param This           A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param Language       A pointer to a three character ISO 639-2 language identifier.

+                        This is the language of the driver name that that the caller

+                        is requesting, and it must match one of the languages specified

+                        in SupportedLanguages.  The number of languages supported by a

+                        driver is up to the driver writer.

+  @param DriverName     A pointer to the Unicode string to return.  This Unicode string

+                        is the name of the driver specified by This in the language

+                        specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by This

+                                and the language specified by Language was returned

+                                in DriverName.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+;

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by an EFI Driver.

+

+  @param This                   A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.

+  @param ControllerHandle       The handle of a controller that the driver specified by

+                                This is managing.  This handle specifies the controller

+                                whose name is to be returned.

+  @param OPTIONAL   ChildHandle The handle of the child controller to retrieve the name

+                                of.  This is an optional parameter that may be NULL.  It

+                                will be NULL for device drivers.  It will also be NULL

+                                for a bus drivers that wish to retrieve the name of the

+                                bus controller.  It will not be NULL for a bus driver

+                                that wishes to retrieve the name of a child controller.

+  @param Language               A pointer to a three character ISO 639-2 language

+                                identifier.  This is the language of the controller name

+                                that that the caller is requesting, and it must match one

+                                of the languages specified in SupportedLanguages.  The

+                                number of languages supported by a driver is up to the

+                                driver writer.

+  @param ControllerName         A pointer to the Unicode string to return.  This Unicode

+                                string is the name of the controller specified by

+                                ControllerHandle and ChildHandle in the language

+                                specified by Language from the point of view of the

+                                driver specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in the

+                                language specified by Language for the driver

+                                specified by This was returned in DriverName.

+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support the

+                                language specified by Language.

+**/

+EFI_STATUS

+EFIAPI

+IdeControllerComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+;

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.uni
new file mode 100644
index 0000000..185c538
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeController.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf
new file mode 100644
index 0000000..5e917c8
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf
@@ -0,0 +1,52 @@
+## @file

+# IDE Controller Init driver that provide IDE_CONTROLLER_INIT protocol and will be used by

+# IDE Bus driver to support platform dependent timing information.

+#

+# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>

+# 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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = IdeController

+  MODULE_UNI_FILE                = IdeController.uni

+  FILE_GUID                      = 99549F44-49BB-4820-B9D2-901329412D67

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = InitializeIdeControllerDriver

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  ComponentName.c

+  IdeController.c

+  IdeController.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiDriverEntryPoint

+  DebugLib

+  UefiLib

+  BaseLib

+  BaseMemoryLib

+  MemoryAllocationLib

+  UefiBootServicesTableLib

+

+[Protocols]

+  gEfiPciIoProtocolGuid             ## BY_START

+  gEfiIdeControllerInitProtocolGuid ## TO_START

+[UserExtensions.TianoCore."ExtraFiles"]

+  IdeControllerExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerExtra.uni
new file mode 100644
index 0000000..07f36d5
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Contributions.txt b/uefi/linaro-edk2/PcAtChipsetPkg/Contributions.txt
new file mode 100644
index 0000000..f87cbd7
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Contributions.txt
@@ -0,0 +1,218 @@
+

+======================

+= Code Contributions =

+======================

+

+To make a contribution to a TianoCore project, follow these steps.

+1. Create a change description in the format specified below to

+   use in the source control commit log.

+2. Your commit message must include your "Signed-off-by" signature,

+   and "Contributed-under" message.

+3. Your "Contributed-under" message explicitly states that the

+   contribution is made under the terms of the specified

+   contribution agreement.  Your "Contributed-under" message

+   must include the name of contribution agreement and version.

+   For example: Contributed-under: TianoCore Contribution Agreement 1.0

+   The "TianoCore Contribution Agreement" is included below in

+   this document.

+4. Submit your code to the TianoCore project using the process

+   that the project documents on its web page.  If the process is

+   not documented, then submit the code on development email list

+   for the project.

+5. It is preferred that contributions are submitted using the same

+   copyright license as the base project. When that is not possible,

+   then contributions using the following licenses can be accepted:

+   * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause

+   * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause

+   * MIT: http://opensource.org/licenses/MIT

+   * Python-2.0: http://opensource.org/licenses/Python-2.0

+   * Zlib: http://opensource.org/licenses/Zlib

+

+   Contributions of code put into the public domain can also be

+   accepted.

+

+   Contributions using other licenses might be accepted, but further

+   review will be required.

+

+=====================================================

+= Change Description / Commit Message / Patch Email =

+=====================================================

+

+Your change description should use the standard format for a

+commit message, and must include your "Signed-off-by" signature

+and the "Contributed-under" message.

+

+== Sample Change Description / Commit Message =

+

+=== Start of sample patch email message ===

+

+From: Contributor Name <contributor@example.com>

+Subject: [PATCH] CodeModule: Brief-single-line-summary

+

+Full-commit-message

+

+Contributed-under: TianoCore Contribution Agreement 1.0

+Signed-off-by: Contributor Name <contributor@example.com>

+---

+

+An extra message for the patch email which will not be considered part

+of the commit message can be added here.

+

+Patch content inline or attached

+

+=== End of sample patch email message ===

+

+=== Notes for sample patch email ===

+

+* The first line of commit message is taken from the email's subject

+  line following [PATCH]. The remaining portion of the commit message

+  is the email's content until the '---' line.

+* git format-patch is one way to create this format

+

+=== Definitions for sample patch email ===

+

+* "CodeModule" is a short idenfier for the affected code.  For

+  example MdePkg, or MdeModulePkg UsbBusDxe.

+* "Brief-single-line-summary" is a short summary of the change.

+* The entire first line should be less than ~70 characters.

+* "Full-commit-message" a verbose multiple line comment describing

+  the change.  Each line should be less than ~70 characters.

+* "Contributed-under" explicitely states that the contribution is

+  made under the terms of the contribtion agreement.  This

+  agreement is included below in this document.

+* "Signed-off-by" is the contributor's signature identifying them

+  by their real/legal name and their email address.

+

+========================================

+= TianoCore Contribution Agreement 1.0 =

+========================================

+

+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,

+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE

+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE

+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE

+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR

+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE

+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS

+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED

+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS

+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE

+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT

+USE THE CONTENT.

+

+Unless otherwise indicated, all Content made available on the TianoCore

+site is provided to you under the terms and conditions of the BSD

+License ("BSD"). A copy of the BSD License is available at

+http://opensource.org/licenses/bsd-license.php

+or when applicable, in the associated License.txt file.

+

+Certain other content may be made available under other licenses as

+indicated in or with such Content. (For example, in a License.txt file.)

+

+You accept and agree to the following terms and conditions for Your

+present and future Contributions submitted to TianoCore site. Except

+for the license granted to Intel hereunder, You reserve all right,

+title, and interest in and to Your Contributions.

+

+== SECTION 1: Definitions ==

+* "You" or "Contributor" shall mean the copyright owner or legal

+  entity authorized by the copyright owner that is making a

+  Contribution hereunder. All other entities that control, are

+  controlled by, or are under common control with that entity are

+  considered to be a single Contributor. For the purposes of this

+  definition, "control" means (i) the power, direct or indirect, to

+  cause the direction or management of such entity, whether by

+  contract or otherwise, or (ii) ownership of fifty percent (50%)

+  or more of the outstanding shares, or (iii) beneficial ownership

+  of such entity.

+* "Contribution" shall mean any original work of authorship,

+  including any modifications or additions to an existing work,

+  that is intentionally submitted by You to the TinaoCore site for

+  inclusion in, or documentation of, any of the Content. For the

+  purposes of this definition, "submitted" means any form of

+  electronic, verbal, or written communication sent to the

+  TianoCore site or its representatives, including but not limited

+  to communication on electronic mailing lists, source code

+  control systems, and issue tracking systems that are managed by,

+  or on behalf of, the TianoCore site for the purpose of

+  discussing and improving the Content, but excluding

+  communication that is conspicuously marked or otherwise

+  designated in writing by You as "Not a Contribution."

+

+== SECTION 2: License for Contributions ==

+* Contributor hereby agrees that redistribution and use of the

+  Contribution in source and binary forms, with or without

+  modification, are permitted provided that the following

+  conditions are met:

+** Redistributions of source code must retain the Contributor's

+   copyright notice, this list of conditions and the following

+   disclaimer.

+** Redistributions in binary form must reproduce the Contributor's

+   copyright notice, this list of conditions and the following

+   disclaimer in the documentation and/or other materials provided

+   with the distribution.

+* Disclaimer. None of the names of Contributor, Intel, or the names

+  of their respective contributors may be used to endorse or

+  promote products derived from this software without specific

+  prior written permission.

+* Contributor grants a license (with the right to sublicense) under

+  claims of Contributor's patents that Contributor can license that

+  are infringed by the Contribution (as delivered by Contributor) to

+  make, use, distribute, sell, offer for sale, and import the

+  Contribution and derivative works thereof solely to the minimum

+  extent necessary for licensee to exercise the granted copyright

+  license; this patent license applies solely to those portions of

+  the Contribution that are unmodified. No hardware per se is

+  licensed.

+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE

+  CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY

+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A

+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+  CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE

+  CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH

+  DAMAGE.

+

+== SECTION 3: Representations ==

+* You represent that You are legally entitled to grant the above

+  license. If your employer(s) has rights to intellectual property

+  that You create that includes Your Contributions, You represent

+  that You have received permission to make Contributions on behalf

+  of that employer, that Your employer has waived such rights for

+  Your Contributions.

+* You represent that each of Your Contributions is Your original

+  creation (see Section 4 for submissions on behalf of others).

+  You represent that Your Contribution submissions include complete

+  details of any third-party license or other restriction

+  (including, but not limited to, related patents and trademarks)

+  of which You are personally aware and which are associated with

+  any part of Your Contributions.

+

+== SECTION 4: Third Party Contributions ==

+* Should You wish to submit work that is not Your original creation,

+  You may submit it to TianoCore site separately from any

+  Contribution, identifying the complete details of its source

+  and of any license or other restriction (including, but not

+  limited to, related patents, trademarks, and license agreements)

+  of which You are personally aware, and conspicuously marking the

+  work as "Submitted on behalf of a third-party: [named here]".

+

+== SECTION 5: Miscellaneous ==

+* Applicable Laws. Any claims arising under or relating to this

+  Agreement shall be governed by the internal substantive laws of

+  the State of Delaware or federal courts located in Delaware,

+  without regard to principles of conflict of laws.

+* Language. This Agreement is in the English language only, which

+  language shall be controlling in all respects, and all versions

+  of this Agreement in any other language shall be for accommodation

+  only and shall not be binding. All communications and notices made

+  or given pursuant to this Agreement, and all documentation and

+  support to be provided, unless otherwise noted, shall be in the

+  English language.

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c
new file mode 100644
index 0000000..e23a2c8
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimer.c
@@ -0,0 +1,988 @@
+/** @file

+  Timer Architectural Protocol module using High Precesion Event Timer (HPET)

+

+  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/Cpu.h>

+#include <Protocol/Timer.h>

+

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/LocalApicLib.h>

+#include <Library/IoApicLib.h>

+

+#include <Register/LocalApic.h>

+#include <Register/IoApic.h>

+#include <Register/Hpet.h>

+

+///

+/// Define value for an invalid HPET Timer index.

+///

+#define HPET_INVALID_TIMER_INDEX  0xff

+

+///

+/// Timer Architectural Protocol function prototypes.

+///

+

+/**

+  This function registers the handler NotifyFunction so it is called every time

+  the timer interrupt fires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is

+  returned.  If the CPU does not support registering a timer interrupt handler,

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR

+  is returned.

+

+  @param  This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  NotifyFunction  The function to call when a timer interrupt fires.  

+                          This function executes at TPL_HIGH_LEVEL.  The DXE 

+                          Core will register a handler for the timer interrupt, 

+                          so it can know how much time has passed.  This 

+                          information is used to signal timer based events.  

+                          NULL will unregister the handler.

+

+  @retval  EFI_SUCCESS            The timer handler was registered.

+  @retval  EFI_UNSUPPORTED        The platform does not support timer interrupts.

+  @retval  EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already

+                                  registered.

+  @retval  EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not

+                                  previously registered.

+  @retval  EFI_DEVICE_ERROR       The timer handler could not be registered.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  );

+

+/**

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+  @param  This         The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod  The rate to program the timer interrupt in 100 nS units.

+                       If the timer hardware is not programmable, then 

+                       EFI_UNSUPPORTED is returned.  If the timer is programmable, 

+                       then the timer period will be rounded up to the nearest 

+                       timer period that is supported by the timer hardware.  

+                       If TimerPeriod is set to 0, then the timer interrupts 

+                       will be disabled.

+

+  @retval  EFI_SUCCESS       The timer period was changed.

+  @retval  EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.

+  @retval  EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  );

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+  @param  This         The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod  A pointer to the timer period to retrieve in 100 ns units.

+                       If 0 is returned, then the timer is currently disabled.

+

+  @retval  EFI_SUCCESS            The timer period was returned in TimerPeriod.

+  @retval  EFI_INVALID_PARAMETER  TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  );

+

+/**

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+  @param  This  The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS       The soft timer interrupt was generated.

+  @retval  EFI_UNSUPPORTEDT  The platform does not support the generation of soft 

+                             timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  );

+  

+///

+/// The handle onto which the Timer Architectural Protocol will be installed.

+///

+EFI_HANDLE   mTimerHandle = NULL;

+

+///

+/// The Timer Architectural Protocol that this driver produces.

+///

+EFI_TIMER_ARCH_PROTOCOL  mTimer = {

+  TimerDriverRegisterHandler,

+  TimerDriverSetTimerPeriod,

+  TimerDriverGetTimerPeriod,

+  TimerDriverGenerateSoftInterrupt

+};

+

+///

+/// Pointer to the CPU Architectural Protocol instance.

+///

+EFI_CPU_ARCH_PROTOCOL  *mCpu = NULL;

+

+///

+/// The notification function to call on every timer interrupt.

+///

+EFI_TIMER_NOTIFY  mTimerNotifyFunction = NULL;

+

+///

+/// The current period of the HPET timer interrupt in 100 ns units.

+///

+UINT64  mTimerPeriod = 0;

+

+///

+/// The number of HPET timer ticks required for the current HPET rate specified by mTimerPeriod.

+///

+UINT64  mTimerCount;

+

+///

+/// Mask used for counter and comparator calculations to adjust for a 32-bit or 64-bit counter.

+///

+UINT64  mCounterMask;

+

+///

+/// The HPET main counter value from the most recent HPET timer interrupt.

+///

+volatile UINT64  mPreviousMainCounter;

+

+volatile UINT64  mPreviousComparator;

+

+///

+/// The index of the HPET timer being managed by this driver.

+///

+UINTN  mTimerIndex;

+

+///

+/// The I/O APIC IRQ that the HPET Timer is mapped if I/O APIC mode is used.

+///

+UINT32  mTimerIrq;

+

+///

+/// Cached state of the HPET General Capabilities register managed by this driver.

+/// Caching the state reduces the number of times the configuration register is read.

+///

+HPET_GENERAL_CAPABILITIES_ID_REGISTER  mHpetGeneralCapabilities;

+

+///

+/// Cached state of the HPET General Configuration register managed by this driver.

+/// Caching the state reduces the number of times the configuration register is read.

+///

+HPET_GENERAL_CONFIGURATION_REGISTER  mHpetGeneralConfiguration;

+

+///

+/// Cached state of the Configuration register for the HPET Timer managed by 

+/// this driver.  Caching the state reduces the number of times the configuration

+/// register is read.

+///

+HPET_TIMER_CONFIGURATION_REGISTER  mTimerConfiguration;

+

+///

+/// Counts the number of HPET Timer interrupts processed by this driver.

+/// Only required for debug.

+///

+volatile UINTN  mNumTicks;

+

+/**

+  Read a 64-bit register from the HPET

+

+  @param  Offset  Specifies the offset of the HPET register to read.

+

+  @return  The 64-bit value read from the HPET register specified by Offset.

+**/

+UINT64

+HpetRead (

+  IN UINTN  Offset

+  )

+{

+  return MmioRead64 (PcdGet32 (PcdHpetBaseAddress) + Offset);

+}

+

+/**

+  Write a 64-bit HPET register.

+

+  @param  Offset  Specifies the ofsfert of the HPET register to write.

+  @param  Value   Specifies the value to write to the HPET register specified by Offset.

+

+  @return  The 64-bit value written to HPET register specified by Offset.

+**/

+UINT64

+HpetWrite (

+  IN UINTN   Offset,

+  IN UINT64  Value

+  )

+{

+  return MmioWrite64 (PcdGet32 (PcdHpetBaseAddress) + Offset, Value);

+}

+

+/**

+  Enable or disable the main counter in the HPET Timer.

+

+  @param  Enable  If TRUE, then enable the main counter in the HPET Timer.

+                  If FALSE, then disable the main counter in the HPET Timer.

+**/

+VOID

+HpetEnable (

+  IN BOOLEAN  Enable

+  )

+{

+  mHpetGeneralConfiguration.Bits.MainCounterEnable = Enable ? 1 : 0;  

+  HpetWrite (HPET_GENERAL_CONFIGURATION_OFFSET, mHpetGeneralConfiguration.Uint64);

+}

+

+/**

+  The interrupt handler for the HPET timer.  This handler clears the HPET interrupt

+  and computes the amount of time that has passed since the last HPET timer interrupt.

+  If a notification function is registered, then the amount of time since the last

+  HPET interrupt is passed to that notification function in 100 ns units.  The HPET

+  time is updated to generate another interrupt in the required time period. 

+

+  @param  InterruptType  The type of interrupt that occured.

+  @param  SystemContext  A pointer to the system context when the interrupt occured.

+**/

+VOID

+EFIAPI

+TimerInterruptHandler (

+  IN EFI_EXCEPTION_TYPE   InterruptType,

+  IN EFI_SYSTEM_CONTEXT   SystemContext

+  )

+{

+  UINT64  MainCounter;

+  UINT64  Comparator;

+  UINT64  TimerPeriod;

+  UINT64  Delta;

+

+  //

+  // Count number of ticks

+  //

+  DEBUG_CODE (mNumTicks++;);

+

+  //

+  // Clear HPET timer interrupt status

+  //

+  HpetWrite (HPET_GENERAL_INTERRUPT_STATUS_OFFSET, LShiftU64 (1, mTimerIndex));

+

+  //

+  // Local APIC EOI

+  //

+  SendApicEoi ();

+

+  //

+  // Disable HPET timer when adjusting the COMPARATOR value to prevent a missed interrupt

+  //

+  HpetEnable (FALSE);

+  

+  //

+  // Capture main counter value

+  //

+  MainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET);

+

+  //

+  // Get the previous comparator counter

+  //

+  mPreviousComparator = HpetRead (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+

+  //

+  // Set HPET COMPARATOR to the value required for the next timer tick

+  //

+  Comparator = (mPreviousComparator + mTimerCount) & mCounterMask;

+

+  if ((mPreviousMainCounter < MainCounter) && (mPreviousComparator > Comparator)) {

+    //

+    // When comparator overflows

+    //

+    HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, Comparator);

+  } else if ((mPreviousMainCounter > MainCounter) && (mPreviousComparator < Comparator)) {

+    //

+    // When main counter overflows

+    //

+    HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (MainCounter + mTimerCount) & mCounterMask);

+  } else {

+    //

+    // When both main counter and comparator do not overflow or both do overflow

+    //

+    if (Comparator > MainCounter) {

+      HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, Comparator);

+    } else {

+      HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (MainCounter + mTimerCount) & mCounterMask);

+    }

+  }

+

+  //

+  // Enable the HPET counter once the new COMPARATOR value has been set.

+  //

+  HpetEnable (TRUE);

+  

+  //

+  // Check to see if there is a registered notification function

+  //

+  if (mTimerNotifyFunction != NULL) {

+    //

+    // Compute time since last notification in 100 ns units (10 ^ -7) 

+    //

+    if (MainCounter > mPreviousMainCounter) {

+      //

+      // Main counter does not overflow

+      //

+      Delta = MainCounter - mPreviousMainCounter;

+    } else {

+      //

+      // Main counter overflows, first usb, then add

+      //

+      Delta = (mCounterMask - mPreviousMainCounter) + MainCounter;

+    }

+    TimerPeriod = DivU64x32 (

+                    MultU64x32 (

+                      Delta & mCounterMask,

+                      mHpetGeneralCapabilities.Bits.CounterClockPeriod

+                      ), 

+                    100000000

+                    );

+                    

+    //

+    // Call registered notification function passing in the time since the last

+    // interrupt in 100 ns units.

+    //    

+    mTimerNotifyFunction (TimerPeriod);

+  }

+  

+  //

+  // Save main counter value

+  //

+  mPreviousMainCounter = MainCounter;

+}

+

+/**

+  This function registers the handler NotifyFunction so it is called every time

+  the timer interrupt fires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is

+  returned.  If the CPU does not support registering a timer interrupt handler,

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR

+  is returned.

+

+  @param  This            The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  NotifyFunction  The function to call when a timer interrupt fires.  

+                          This function executes at TPL_HIGH_LEVEL.  The DXE 

+                          Core will register a handler for the timer interrupt, 

+                          so it can know how much time has passed.  This 

+                          information is used to signal timer based events.  

+                          NULL will unregister the handler.

+

+  @retval  EFI_SUCCESS            The timer handler was registered.

+  @retval  EFI_UNSUPPORTED        The platform does not support timer interrupts.

+  @retval  EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already

+                                  registered.

+  @retval  EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not

+                                  previously registered.

+  @retval  EFI_DEVICE_ERROR       The timer handler could not be registered.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+{

+  //

+  // Check for invalid parameters

+  //

+  if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  //

+  // Cache the registered notification function

+  //

+  mTimerNotifyFunction = NotifyFunction;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+  @param  This         The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod  The rate to program the timer interrupt in 100 nS units.

+                       If the timer hardware is not programmable, then 

+                       EFI_UNSUPPORTED is returned.  If the timer is programmable, 

+                       then the timer period will be rounded up to the nearest 

+                       timer period that is supported by the timer hardware.  

+                       If TimerPeriod is set to 0, then the timer interrupts 

+                       will be disabled.

+

+  @retval  EFI_SUCCESS       The timer period was changed.

+  @retval  EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.

+  @retval  EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+{

+  UINT64                         MainCounter;

+  UINT64                         Delta;

+  UINT64                         CurrentComparator;

+  HPET_TIMER_MSI_ROUTE_REGISTER  HpetTimerMsiRoute;

+  

+  //

+  // Disable HPET timer when adjusting the timer period

+  //

+  HpetEnable (FALSE);

+  

+  if (TimerPeriod == 0) {

+    if (mTimerPeriod != 0) {

+      //

+      // Check if there is possibly a pending interrupt

+      //

+      MainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET);

+      if (MainCounter < mPreviousMainCounter) {

+        Delta = (mCounterMask - mPreviousMainCounter) + MainCounter;

+      } else { 

+        Delta = MainCounter - mPreviousMainCounter;

+      }

+      if ((Delta & mCounterMask) >= mTimerCount) {

+        //

+        // Interrupt still happens after disable HPET, wait to be processed

+        // Wait until interrupt is processed and comparator is increased

+        //

+        CurrentComparator = HpetRead (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+        while (CurrentComparator == mPreviousComparator) {

+          CurrentComparator = HpetRead (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+          CpuPause();

+        }

+      }

+    }

+

+    //

+    // If TimerPeriod is 0, then mask HPET Timer interrupts

+    //

+    

+    if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0 && FeaturePcdGet (PcdHpetMsiEnable)) {

+      //

+      // Disable HPET MSI interrupt generation

+      //

+      mTimerConfiguration.Bits.MsiInterruptEnable = 0;

+    } else {

+      //

+      // Disable I/O APIC Interrupt

+      //

+      IoApicEnableInterrupt (mTimerIrq, FALSE);

+    }

+    

+    //

+    // Disable HPET timer interrupt 

+    //

+    mTimerConfiguration.Bits.InterruptEnable = 0;

+    HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64);

+  } else {

+    //

+    // Convert TimerPeriod to femtoseconds and divide by the number if femtoseconds 

+    // per tick of the HPET counter to determine the number of HPET counter ticks

+    // in TimerPeriod 100 ns units.

+    // 

+    mTimerCount = DivU64x32 (

+                    MultU64x32 (TimerPeriod, 100000000),

+                    mHpetGeneralCapabilities.Bits.CounterClockPeriod

+                    );

+

+    //

+    // Program the HPET Comparator with the number of ticks till the next interrupt

+    //

+    MainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET);

+    if (MainCounter > mPreviousMainCounter) {

+      Delta = MainCounter - mPreviousMainCounter;

+    } else { 

+      Delta = (mCounterMask - mPreviousMainCounter) + MainCounter;

+    }

+    if ((Delta & mCounterMask) >= mTimerCount) {

+      HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (MainCounter + 1) & mCounterMask);

+    } else {  

+      HpetWrite (HPET_TIMER_COMPARATOR_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, (mPreviousMainCounter + mTimerCount) & mCounterMask);

+    }

+    

+    //

+    // Enable HPET Timer interrupt generation

+    //

+    if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0 && FeaturePcdGet (PcdHpetMsiEnable)) {

+      //

+      // Program MSI Address and MSI Data values in the selected HPET Timer

+      // Program HPET register with APIC ID of current BSP in case BSP has been switched

+      //

+      HpetTimerMsiRoute.Bits.Address = GetApicMsiAddress ();

+      HpetTimerMsiRoute.Bits.Value   = (UINT32)GetApicMsiValue (PcdGet8 (PcdHpetLocalApicVector), LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY, FALSE, FALSE);

+      HpetWrite (HPET_TIMER_MSI_ROUTE_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, HpetTimerMsiRoute.Uint64);

+      //

+      // Enable HPET MSI Interrupt

+      //

+      mTimerConfiguration.Bits.MsiInterruptEnable = 1;

+    } else {

+      //

+      // Enable timer interrupt through I/O APIC

+      // Program IOAPIC register with APIC ID of current BSP in case BSP has been switched

+      //

+      IoApicConfigureInterrupt (mTimerIrq, PcdGet8 (PcdHpetLocalApicVector), IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY, TRUE, FALSE);

+      IoApicEnableInterrupt (mTimerIrq, TRUE);

+    }

+

+    //

+    // Enable HPET Interrupt Generation

+    //

+    mTimerConfiguration.Bits.InterruptEnable = 1;

+    HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64);

+  }

+    

+  //

+  // Save the new timer period

+  //

+  mTimerPeriod = TimerPeriod;

+

+  //

+  // Enable the HPET counter once new timer period has been established

+  // The HPET counter should run even if the HPET Timer interrupts are

+  // disabled.  This is used to account for time passed while the interrupt

+  // is disabled.

+  //

+  HpetEnable (TRUE);

+  

+  return EFI_SUCCESS;

+}

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+  @param  This         The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod  A pointer to the timer period to retrieve in 100 ns units.

+                       If 0 is returned, then the timer is currently disabled.

+

+  @retval  EFI_SUCCESS            The timer period was returned in TimerPeriod.

+  @retval  EFI_INVALID_PARAMETER  TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mTimerPeriod;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+  @param  This  The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval  EFI_SUCCESS       The soft timer interrupt was generated.

+  @retval  EFI_UNSUPPORTEDT  The platform does not support the generation of soft 

+                             timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+{

+  UINT64   MainCounter;

+  EFI_TPL  Tpl;

+  UINT64   TimerPeriod;

+  UINT64   Delta;

+

+  //

+  // Disable interrupts

+  //  

+  Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+  

+  //

+  // Capture main counter value

+  //

+  MainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET);

+

+  //

+  // Check to see if there is a registered notification function

+  //

+  if (mTimerNotifyFunction != NULL) {

+    //

+    // Compute time since last interrupt in 100 ns units (10 ^ -7) 

+    //

+    if (MainCounter > mPreviousMainCounter) {

+      //

+      // Main counter does not overflow

+      //

+      Delta = MainCounter - mPreviousMainCounter;

+    } else {

+      //

+      // Main counter overflows, first usb, then add

+      //

+      Delta = (mCounterMask - mPreviousMainCounter) + MainCounter;

+    }

+

+    TimerPeriod = DivU64x32 (

+                    MultU64x32 (

+                      Delta & mCounterMask,

+                      mHpetGeneralCapabilities.Bits.CounterClockPeriod

+                      ), 

+                    100000000

+                    );

+                    

+    //

+    // Call registered notification function passing in the time since the last

+    // interrupt in 100 ns units.

+    //    

+    mTimerNotifyFunction (TimerPeriod);

+  }

+

+  //

+  // Save main counter value

+  //

+  mPreviousMainCounter = MainCounter;

+  

+  //

+  // Restore interrupts

+  //  

+  gBS->RestoreTPL (Tpl);

+  

+  return EFI_SUCCESS;

+}

+

+/**

+  Initialize the Timer Architectural Protocol driver

+

+  @param  ImageHandle  ImageHandle of the loaded driver

+  @param  SystemTable  Pointer to the System Table

+

+  @retval  EFI_SUCCESS           Timer Architectural Protocol created

+  @retval  EFI_OUT_OF_RESOURCES  Not enough resources available to initialize driver.

+  @retval  EFI_DEVICE_ERROR      A device error occured attempting to initialize the driver.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverInitialize (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                             Status;

+  UINTN                                  TimerIndex;

+  UINTN                                  MsiTimerIndex;

+  HPET_TIMER_MSI_ROUTE_REGISTER          HpetTimerMsiRoute;

+

+  DEBUG ((DEBUG_INFO, "Init HPET Timer Driver\n"));

+

+  //

+  // Make sure the Timer Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);

+

+  //

+  // Find the CPU architectural protocol.

+  //

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Retrieve HPET Capabilities and Configuration Information

+  //  

+  mHpetGeneralCapabilities.Uint64  = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);

+  mHpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);

+ 

+  //

+  // If Revision is not valid, then ASSERT() and unload the driver because the HPET 

+  // device is not present.

+  //  

+  ASSERT (mHpetGeneralCapabilities.Uint64 != 0);

+  ASSERT (mHpetGeneralCapabilities.Uint64 != 0xFFFFFFFFFFFFFFFFULL);

+  if (mHpetGeneralCapabilities.Uint64 == 0 || mHpetGeneralCapabilities.Uint64 == 0xFFFFFFFFFFFFFFFFULL) {

+    DEBUG ((DEBUG_ERROR, "HPET device is not present.  Unload HPET driver.\n"));

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Force the HPET timer to be disabled while setting everything up

+  //

+  HpetEnable (FALSE);

+

+  //

+  // Dump HPET Configuration Information

+  //  

+  DEBUG_CODE (

+    DEBUG ((DEBUG_INFO, "HPET Base Address = 0x%08x\n", PcdGet32 (PcdHpetBaseAddress)));

+    DEBUG ((DEBUG_INFO, "  HPET_GENERAL_CAPABILITIES_ID  = 0x%016lx\n", mHpetGeneralCapabilities));

+    DEBUG ((DEBUG_INFO, "  HPET_GENERAL_CONFIGURATION    = 0x%016lx\n", mHpetGeneralConfiguration.Uint64));

+    DEBUG ((DEBUG_INFO, "  HPET_GENERAL_INTERRUPT_STATUS = 0x%016lx\n", HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET)));

+    DEBUG ((DEBUG_INFO, "  HPET_MAIN_COUNTER             = 0x%016lx\n", HpetRead (HPET_MAIN_COUNTER_OFFSET)));

+    DEBUG ((DEBUG_INFO, "  HPET Main Counter Period      = %d (fs)\n", mHpetGeneralCapabilities.Bits.CounterClockPeriod));

+    for (TimerIndex = 0; TimerIndex <= mHpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {

+      DEBUG ((DEBUG_INFO, "  HPET_TIMER%d_CONFIGURATION     = 0x%016lx\n", TimerIndex, HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE)));

+      DEBUG ((DEBUG_INFO, "  HPET_TIMER%d_COMPARATOR        = 0x%016lx\n", TimerIndex, HpetRead (HPET_TIMER_COMPARATOR_OFFSET    + TimerIndex * HPET_TIMER_STRIDE)));

+      DEBUG ((DEBUG_INFO, "  HPET_TIMER%d_MSI_ROUTE         = 0x%016lx\n", TimerIndex, HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET     + TimerIndex * HPET_TIMER_STRIDE)));

+    }

+  );

+  

+  //

+  // Capture the current HPET main counter value.

+  //

+  mPreviousMainCounter = HpetRead (HPET_MAIN_COUNTER_OFFSET);

+  

+  //

+  // Determine the interrupt mode to use for the HPET Timer.  

+  // Look for MSI first, then unused PIC mode interrupt, then I/O APIC mode interrupt

+  //  

+  MsiTimerIndex = HPET_INVALID_TIMER_INDEX;

+  mTimerIndex   = HPET_INVALID_TIMER_INDEX;

+  for (TimerIndex = 0; TimerIndex <= mHpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {

+    //

+    // Read the HPET Timer Capabilities and Configuration register

+    //

+    mTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE);

+    

+    //

+    // Check to see if this HPET Timer supports MSI 

+    //

+    if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0) {

+      //

+      // Save the index of the first HPET Timer that supports MSI interrupts

+      //

+      if (MsiTimerIndex == HPET_INVALID_TIMER_INDEX) {

+        MsiTimerIndex = TimerIndex;

+      }

+    }

+    

+    //

+    // Check to see if this HPET Timer supports I/O APIC interrupts

+    //

+    if (mTimerConfiguration.Bits.InterruptRouteCapability != 0) {

+      //

+      // Save the index of the first HPET Timer that supports I/O APIC interrupts

+      //

+      if (mTimerIndex == HPET_INVALID_TIMER_INDEX) {

+        mTimerIndex = TimerIndex;

+        mTimerIrq   = (UINT32)LowBitSet32 (mTimerConfiguration.Bits.InterruptRouteCapability);

+      }

+    }

+  }

+

+  if (FeaturePcdGet (PcdHpetMsiEnable) && MsiTimerIndex != HPET_INVALID_TIMER_INDEX) {

+    //

+    // Use MSI interrupt if supported

+    //

+    mTimerIndex  = MsiTimerIndex;

+

+    //

+    // Program MSI Address and MSI Data values in the selected HPET Timer

+    //

+    HpetTimerMsiRoute.Bits.Address = GetApicMsiAddress ();

+    HpetTimerMsiRoute.Bits.Value   = (UINT32)GetApicMsiValue (PcdGet8 (PcdHpetLocalApicVector), LOCAL_APIC_DELIVERY_MODE_LOWEST_PRIORITY, FALSE, FALSE);

+    HpetWrite (HPET_TIMER_MSI_ROUTE_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, HpetTimerMsiRoute.Uint64);

+

+    //

+    // Read the HPET Timer Capabilities and Configuration register and initialize for MSI mode

+    //   Clear LevelTriggeredInterrupt to use edge triggered interrupts when in MSI mode

+    //

+    mTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+    mTimerConfiguration.Bits.LevelTriggeredInterrupt = 0;

+  } else {

+    //

+    // If no HPET timers support MSI or I/O APIC modes, then ASSERT() and unload the driver.

+    //

+    ASSERT (mTimerIndex != HPET_INVALID_TIMER_INDEX);

+    if (mTimerIndex == HPET_INVALID_TIMER_INDEX) {

+      DEBUG ((DEBUG_ERROR, "No HPET timers support MSI or I/O APIC mode.  Unload HPET driver.\n"));

+      return EFI_DEVICE_ERROR;

+    }

+    

+    //

+    // Initialize I/O APIC entry for HPET Timer Interrupt

+    //   Fixed Delivery Mode, Level Triggered, Asserted Low

+    //

+    IoApicConfigureInterrupt (mTimerIrq, PcdGet8 (PcdHpetLocalApicVector), IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY, TRUE, FALSE);

+

+    //

+    // Read the HPET Timer Capabilities and Configuration register and initialize for I/O APIC mode

+    //   Clear MsiInterruptCapability to force rest of driver to use I/O APIC mode

+    //   Set LevelTriggeredInterrupt to use level triggered interrupts when in I/O APIC mode

+    //   Set InterruptRoute field based in mTimerIrq

+    //

+    mTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+    mTimerConfiguration.Bits.LevelTriggeredInterrupt = 1;

+    mTimerConfiguration.Bits.InterruptRoute          = mTimerIrq;

+  }

+

+  //

+  // Configure the selected HPET Timer with settings common to both MSI mode and I/O APIC mode

+  //   Clear InterruptEnable to keep interrupts disabled until full init is complete 

+  //   Clear PeriodicInterruptEnable to use one-shot mode 

+  //   Configure as a 32-bit counter  

+  //

+  mTimerConfiguration.Bits.InterruptEnable         = 0;

+  mTimerConfiguration.Bits.PeriodicInterruptEnable = 0;

+  mTimerConfiguration.Bits.CounterSizeEnable       = 1;

+  HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64);

+  

+  //

+  // Read the HPET Timer Capabilities and Configuration register back again.

+  // CounterSizeEnable will be read back as a 0 if it is a 32-bit only timer

+  //

+  mTimerConfiguration.Uint64 = HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE);

+  if ((mTimerConfiguration.Bits.CounterSizeEnable == 1) && (sizeof (UINTN) == sizeof (UINT64))) {

+    DEBUG ((DEBUG_INFO, "Choose 64-bit HPET timer.\n"));

+    //

+    // 64-bit BIOS can use 64-bit HPET timer

+    //

+    mCounterMask = 0xffffffffffffffffULL;

+    //

+    // Set timer back to 64-bit

+    //

+    mTimerConfiguration.Bits.CounterSizeEnable = 0;

+    HpetWrite (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE, mTimerConfiguration.Uint64);

+  } else {

+    DEBUG ((DEBUG_INFO, "Choose 32-bit HPET timer.\n"));

+    mCounterMask = 0x00000000ffffffffULL;

+  }

+

+  //

+  // Install interrupt handler for selected HPET Timer

+  //

+  Status = mCpu->RegisterInterruptHandler (mCpu, PcdGet8 (PcdHpetLocalApicVector), TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Unable to register HPET interrupt with CPU Arch Protocol.  Unload HPET driver.\n"));

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Force the HPET Timer to be enabled at its default period

+  //

+  Status = TimerDriverSetTimerPeriod (&mTimer, PcdGet64 (PcdHpetDefaultTimerPeriod));

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Unable to set HPET default timer rate.  Unload HPET driver.\n"));

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Show state of enabled HPET timer

+  //

+  DEBUG_CODE (

+    if (mTimerConfiguration.Bits.MsiInterruptCapablity != 0 && FeaturePcdGet (PcdHpetMsiEnable)) {

+      DEBUG ((DEBUG_INFO, "HPET Interrupt Mode MSI\n"));

+    } else {

+      DEBUG ((DEBUG_INFO, "HPET Interrupt Mode I/O APIC\n"));

+      DEBUG ((DEBUG_INFO, "HPET I/O APIC IRQ         = 0x%02x\n",  mTimerIrq));

+    }  

+    DEBUG ((DEBUG_INFO, "HPET Interrupt Vector     = 0x%02x\n",    PcdGet8 (PcdHpetLocalApicVector)));

+    DEBUG ((DEBUG_INFO, "HPET Counter Mask         = 0x%016lx\n",  mCounterMask));

+    DEBUG ((DEBUG_INFO, "HPET Timer Period         = %d\n",        mTimerPeriod));

+    DEBUG ((DEBUG_INFO, "HPET Timer Count          = 0x%016lx\n",  mTimerCount));

+    DEBUG ((DEBUG_INFO, "HPET_TIMER%d_CONFIGURATION = 0x%016lx\n", mTimerIndex, HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + mTimerIndex * HPET_TIMER_STRIDE)));

+    DEBUG ((DEBUG_INFO, "HPET_TIMER%d_COMPARATOR    = 0x%016lx\n", mTimerIndex, HpetRead (HPET_TIMER_COMPARATOR_OFFSET    + mTimerIndex * HPET_TIMER_STRIDE)));

+    DEBUG ((DEBUG_INFO, "HPET_TIMER%d_MSI_ROUTE     = 0x%016lx\n", mTimerIndex, HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET     + mTimerIndex * HPET_TIMER_STRIDE)));

+

+    //

+    // Wait for a few timer interrupts to fire before continuing

+    // 

+    while (mNumTicks < 10);

+  );

+ 

+  //

+  // Install the Timer Architectural Protocol onto a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mTimerHandle,

+                  &gEfiTimerArchProtocolGuid, &mTimer,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
new file mode 100644
index 0000000..8cc4c4d
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
@@ -0,0 +1,64 @@
+## @file

+# Timer Architectural Protocol module using High Precesion Event Timer (HPET).

+#

+# Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>

+# 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.             

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = HpetTimerDxe

+  MODULE_UNI_FILE                = HpetTimerDxe.uni

+  FILE_GUID                      = 6CE6B0DE-781C-4f6c-B42D-98346C614BEC

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = TimerDriverInitialize

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+#

+

+[Sources]

+  HpetTimer.c

+  

+[Packages]

+  MdePkg/MdePkg.dec

+  UefiCpuPkg/UefiCpuPkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+  

+[LibraryClasses]

+  PcdLib

+  IoLib

+  DebugLib

+  UefiDriverEntryPoint

+  UefiBootServicesTableLib

+  BaseLib

+  LocalApicLib

+  IoApicLib

+

+[Protocols]

+  gEfiTimerArchProtocolGuid                     ## PRODUCES

+  gEfiCpuArchProtocolGuid                       ## CONSUMES

+

+[FeaturePcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetMsiEnable    ## CONSUMES

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress          ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetLocalApicVector      ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetDefaultTimerPeriod   ## CONSUMES

+

+[Depex]

+  gEfiCpuArchProtocolGuid

+[UserExtensions.TianoCore."ExtraFiles"]

+  HpetTimerDxeExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.uni b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.uni
new file mode 100644
index 0000000..1d0d88c
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxeExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxeExtra.uni
new file mode 100644
index 0000000..d7ca415
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxeExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Include/Guid/PcAtChipsetTokenSpace.h b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Guid/PcAtChipsetTokenSpace.h
new file mode 100644
index 0000000..5e6991d
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Guid/PcAtChipsetTokenSpace.h
@@ -0,0 +1,25 @@
+/** @file

+  GUID for PcAtChipsetPkg PCD Token Space.

+

+  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef _PCATCHIPSET_TOKEN_SPACE_GUID_H_

+#define _PCATCHIPSET_TOKEN_SPACE_GUID_H_

+

+#define PCATCHIPSET_TOKEN_SPACE_GUID \

+  { \

+    0x326ae723, 0xae32, 0x4589, { 0x98, 0xb8, 0xca, 0xc2, 0x3c, 0xdc, 0xc1, 0xb1 } \

+  }

+

+extern EFI_GUID gPcAtChipsetPkgTokenSpaceGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Include/Library/IoApicLib.h b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Library/IoApicLib.h
new file mode 100644
index 0000000..c3eb0ce
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Library/IoApicLib.h
@@ -0,0 +1,105 @@
+/** @file

+  Public include file for I/O APIC library.

+

+  I/O APIC library assumes I/O APIC is enabled. It does not

+  handles cases where I/O APIC is disabled.

+

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+#ifndef __IO_APIC_LIB_H__

+#define __IO_APIC_LIB_H__

+

+/**

+  Read a 32-bit I/O APIC register.

+

+  If Index is >= 0x100, then ASSERT().

+  

+  @param  Index  Specifies the I/O APIC register to read.

+

+  @return  The 32-bit value read from the I/O APIC register specified by Index.

+**/

+UINT32

+EFIAPI

+IoApicRead (

+  IN UINTN  Index

+  );

+

+/**

+  Write a 32-bit I/O APIC register.

+

+  If Index is >= 0x100, then ASSERT().

+  

+  @param  Index  Specifies the I/O APIC register to write.

+  @param  Value  Specifies the value to write to the I/O APIC register specified by Index.

+

+  @return  The 32-bit value written to I/O APIC register specified by Index.

+**/

+UINT32

+EFIAPI

+IoApicWrite (

+  IN UINTN   Index,

+  IN UINT32  Value

+  );

+

+/**

+  Set the interrupt mask of an I/O APIC interrupt.

+

+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). 

+  

+  @param  Irq     Specifies the I/O APIC interrupt to enable or disable.

+  @param  Enable  If TRUE, then enable the I/O APIC interrupt specified by Irq.

+                  If FALSE, then disable the I/O APIC interrupt specified by Irq.

+**/

+VOID

+EFIAPI

+IoApicEnableInterrupt (

+  IN UINTN    Irq,

+  IN BOOLEAN  Enable

+  );

+

+/**

+  Configures an I/O APIC interrupt.

+  

+  Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical

+  mode to the Local APIC of the currntly executing CPU.  The default state of the 

+  entry is for the interrupt to be disabled (masked).  IoApicEnableInterrupts() must

+  be used to enable(unmask) the I/O APIC Interrupt.

+

+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). 

+  If Vector >= 0x100, then ASSERT().

+  If DeliveryMode is not supported, then ASSERT().

+

+  @param  Irq             Specifies the I/O APIC interrupt to initialize.

+  @param  Vector          The 8-bit interrupt vector associated with the I/O APIC

+                          Interrupt.  Must be in the range 0x10..0xFE.

+  @param  DeliveryMode    A 3-bit value that specifies how the recept of the I/O APIC

+                          interrupt is handled.  The only supported values are:

+                            0: IO_APIC_DELIVERY_MODE_FIXED

+                            1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY

+                            2: IO_APIC_DELIVERY_MODE_SMI

+                            4: IO_APIC_DELIVERY_MODE_NMI

+                            5: IO_APIC_DELIVERY_MODE_INIT

+                            7: IO_APIC_DELIVERY_MODE_EXTINT

+  @param  LevelTriggered  TRUE specifies a level triggered interrupt.

+                          FALSE specifies an edge triggered interrupt.

+  @param  AssertionLevel  TRUE specified an active high interrupt.

+                          FALSE specifies an active low interrupt.

+**/

+VOID

+EFIAPI

+IoApicConfigureInterrupt (

+  IN UINTN    Irq,

+  IN UINTN    Vector,

+  IN UINTN    DeliveryMode,

+  IN BOOLEAN  LevelTriggered,

+  IN BOOLEAN  AssertionLevel

+  );

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/Hpet.h b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/Hpet.h
new file mode 100644
index 0000000..2933767
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/Hpet.h
@@ -0,0 +1,106 @@
+/** @file

+  HPET register definitions from the IA-PC HPET (High Precision Event Timers) 

+  Specification, Revision 1.0a, October 2004.

+

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __HPET_REGISTER_H__

+#define __HPET_REGISTER_H__

+

+///

+/// HPET General Register Offsets

+///

+#define HPET_GENERAL_CAPABILITIES_ID_OFFSET   0x000

+#define HPET_GENERAL_CONFIGURATION_OFFSET     0x010

+#define HPET_GENERAL_INTERRUPT_STATUS_OFFSET  0x020

+

+///

+/// HPET Timer Register Offsets

+///

+#define HPET_MAIN_COUNTER_OFFSET              0x0F0

+#define HPET_TIMER_CONFIGURATION_OFFSET       0x100

+#define HPET_TIMER_COMPARATOR_OFFSET          0x108

+#define HPET_TIMER_MSI_ROUTE_OFFSET           0x110

+

+///

+/// Stride between sets of HPET Timer Registers

+///

+#define HPET_TIMER_STRIDE         0x20

+

+#pragma pack(1)

+

+///

+/// HPET General Capabilities and ID Register

+///

+typedef union {

+  struct {

+    UINT32  Revision:8;

+    UINT32  NumberOfTimers:5;

+    UINT32  CounterSize:1;

+    UINT32  Reserved0:1;

+    UINT32  LegacyRoute:1;

+    UINT32  VendorId:16;

+    UINT32  CounterClockPeriod:32;

+  } Bits;

+  UINT64  Uint64;

+} HPET_GENERAL_CAPABILITIES_ID_REGISTER;

+

+///

+/// HPET General Configuration Register

+///

+typedef union {

+  struct {

+    UINT32  MainCounterEnable:1;

+    UINT32  LegacyRouteEnable:1;

+    UINT32  Reserved0:30;

+    UINT32  Reserved1:32;

+  } Bits;

+  UINT64  Uint64;

+} HPET_GENERAL_CONFIGURATION_REGISTER;

+

+///

+/// HPET Timer Configuration Register

+///

+typedef union {

+  struct {

+    UINT32  Reserved0:1;

+    UINT32  LevelTriggeredInterrupt:1;

+    UINT32  InterruptEnable:1;

+    UINT32  PeriodicInterruptEnable:1;

+    UINT32  PeriodicInterruptCapablity:1;

+    UINT32  CounterSizeCapablity:1;

+    UINT32  ValueSetEnable:1;

+    UINT32  Reserved1:1;

+    UINT32  CounterSizeEnable:1;

+    UINT32  InterruptRoute:5;

+    UINT32  MsiInterruptEnable:1;

+    UINT32  MsiInterruptCapablity:1;

+    UINT32  Reserved2:16;

+    UINT32  InterruptRouteCapability;

+  } Bits;

+  UINT64  Uint64;

+} HPET_TIMER_CONFIGURATION_REGISTER;

+

+///

+/// HPET Timer MSI Route Register

+///

+typedef union {

+  struct {

+    UINT32  Value:32;

+    UINT32  Address:32;

+  } Bits;

+  UINT64  Uint64;

+} HPET_TIMER_MSI_ROUTE_REGISTER;

+

+#pragma pack()

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/IoApic.h b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/IoApic.h
new file mode 100644
index 0000000..d6e73be
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Include/Register/IoApic.h
@@ -0,0 +1,86 @@
+/** @file

+  I/O APIC Register Definitions from 82093AA I/O Advanced Programmable Interrupt 

+  Controller (IOAPIC), 1996.

+  

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#ifndef __IO_APIC_H__

+#define __IO_APIC_H__

+

+///

+/// I/O APIC Register Offsets

+///

+#define IOAPIC_INDEX_OFFSET  0x00

+#define IOAPIC_DATA_OFFSET   0x10

+

+///

+/// I/O APIC Indirect Register Indexes

+///

+#define IO_APIC_IDENTIFICATION_REGISTER_INDEX  0x00

+#define IO_APIC_VERSION_REGISTER_INDEX         0x01

+#define IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX  0x10

+

+///

+/// I/O APIC Interrupt Deliver Modes

+///

+#define IO_APIC_DELIVERY_MODE_FIXED            0

+#define IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY  1

+#define IO_APIC_DELIVERY_MODE_SMI              2

+#define IO_APIC_DELIVERY_MODE_NMI              4

+#define IO_APIC_DELIVERY_MODE_INIT             5

+#define IO_APIC_DELIVERY_MODE_EXTINT           7

+

+#pragma pack(1)

+

+typedef union {

+  struct {

+    UINT32  Reserved0:24;

+    UINT32  Identification:4;

+    UINT32  Reserved1:4;

+  } Bits;

+  UINT32  Uint32;

+} IO_APIC_IDENTIFICATION_REGISTER;

+

+typedef union {

+  struct {

+    UINT32  Version:8;

+    UINT32  Reserved0:8;

+    UINT32  MaximumRedirectionEntry:8;

+    UINT32  Reserved1:8;

+  } Bits;

+  UINT32  Uint32;

+} IO_APIC_VERSION_REGISTER;

+

+typedef union {

+  struct {

+    UINT32  Vector:          8;

+    UINT32  DeliveryMode:    3;

+    UINT32  DestinationMode: 1;

+    UINT32  DeliveryStatus:  1;

+    UINT32  Polarity:        1;

+    UINT32  RemoteIRR:       1;

+    UINT32  TriggerMode:     1;

+    UINT32  Mask:            1;

+    UINT32  Reserved0:       15;

+    UINT32  Reserved1:       24;

+    UINT32  DestinationID:   8;

+  } Bits;

+  struct {

+    UINT32  Low;

+    UINT32  High;

+  } Uint32;

+  UINT64  Uint64;

+} IO_APIC_REDIRECTION_TABLE_ENTRY;

+

+#pragma pack()

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/ComponentName.c b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/ComponentName.c
new file mode 100644
index 0000000..0d634ea
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/ComponentName.c
@@ -0,0 +1,307 @@
+/** @file

+    UEFI Component Name(2) protocol implementation for IsaAcpi driver.

+

+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>

+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.             

+**/

+

+#include "PcatIsaAcpi.h"

+

+//

+// EFI Component Name Functions

+//

+/**

+  Retrieves a Unicode string that is the user readable name of the driver.

+

+  This function retrieves the user readable name of a driver in the form of a

+  Unicode string. If the driver specified by This has a user readable name in

+  the language specified by Language, then a pointer to the driver name is

+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified

+  by This does not support the language specified by Language,

+  then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language. This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified

+                                in RFC 4646 or ISO 639-2 language code format.

+

+  @param  DriverName[out]       A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                driver specified by This in the language

+                                specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by

+                                This and the language specified by Language was

+                                returned in DriverName.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by a driver.

+

+  This function retrieves the user readable name of the controller specified by

+  ControllerHandle and ChildHandle in the form of a Unicode string. If the

+  driver specified by This has a user readable name in the language specified by

+  Language, then a pointer to the controller name is returned in ControllerName,

+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently

+  managing the controller specified by ControllerHandle and ChildHandle,

+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not

+  support the language specified by Language, then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  ControllerHandle[in]  The handle of a controller that the driver

+                                specified by This is managing.  This handle

+                                specifies the controller whose name is to be

+                                returned.

+

+  @param  ChildHandle[in]       The handle of the child controller to retrieve

+                                the name of.  This is an optional parameter that

+                                may be NULL.  It will be NULL for device

+                                drivers.  It will also be NULL for a bus drivers

+                                that wish to retrieve the name of the bus

+                                controller.  It will not be NULL for a bus

+                                driver that wishes to retrieve the name of a

+                                child controller.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language.  This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified in

+                                RFC 4646 or ISO 639-2 language code format.

+

+  @param  ControllerName[out]   A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                controller specified by ControllerHandle and

+                                ChildHandle in the language specified by

+                                Language from the point of view of the driver

+                                specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in

+                                the language specified by Language for the

+                                driver specified by This was returned in

+                                DriverName.

+

+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.

+

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_HANDLE                   ChildHandle        OPTIONAL,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **ControllerName

+  );

+

+//

+// EFI Component Name Protocol

+//

+

+EFI_COMPONENT_NAME2_PROTOCOL gPcatIsaAcpiComponentName2 = {

+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     PcatIsaAcpiComponentNameGetDriverName,

+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PcatIsaAcpiComponentNameGetControllerName,

+  "en"

+};

+

+EFI_COMPONENT_NAME_PROTOCOL  gPcatIsaAcpiComponentName = {

+  PcatIsaAcpiComponentNameGetDriverName,

+  PcatIsaAcpiComponentNameGetControllerName,

+  "eng"

+};

+

+

+EFI_UNICODE_STRING_TABLE mPcatIsaAcpiDriverNameTable[] = {

+  {

+    "eng;en",

+    L"PC-AT ISA Device Enumeration Driver"

+  },

+  {

+    NULL,

+    NULL

+  }

+};

+

+/**

+  Retrieves a Unicode string that is the user readable name of the driver.

+

+  This function retrieves the user readable name of a driver in the form of a

+  Unicode string. If the driver specified by This has a user readable name in

+  the language specified by Language, then a pointer to the driver name is

+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified

+  by This does not support the language specified by Language,

+  then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language. This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified

+                                in RFC 4646 or ISO 639-2 language code format.

+

+  @param  DriverName[out]       A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                driver specified by This in the language

+                                specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by

+                                This and the language specified by Language was

+                                returned in DriverName.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+{

+  return LookupUnicodeString2 (

+           Language,

+           This->SupportedLanguages,

+           mPcatIsaAcpiDriverNameTable, 

+           DriverName,

+           (BOOLEAN)(This == &gPcatIsaAcpiComponentName)

+           );

+}

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by a driver.

+

+  This function retrieves the user readable name of the controller specified by

+  ControllerHandle and ChildHandle in the form of a Unicode string. If the

+  driver specified by This has a user readable name in the language specified by

+  Language, then a pointer to the controller name is returned in ControllerName,

+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently

+  managing the controller specified by ControllerHandle and ChildHandle,

+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not

+  support the language specified by Language, then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  ControllerHandle[in]  The handle of a controller that the driver

+                                specified by This is managing.  This handle

+                                specifies the controller whose name is to be

+                                returned.

+

+  @param  ChildHandle[in]       The handle of the child controller to retrieve

+                                the name of.  This is an optional parameter that

+                                may be NULL.  It will be NULL for device

+                                drivers.  It will also be NULL for a bus drivers

+                                that wish to retrieve the name of the bus

+                                controller.  It will not be NULL for a bus

+                                driver that wishes to retrieve the name of a

+                                child controller.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language.  This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified in

+                                RFC 4646 or ISO 639-2 language code format.

+

+  @param  ControllerName[out]   A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                controller specified by ControllerHandle and

+                                ChildHandle in the language specified by

+                                Language from the point of view of the driver

+                                specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in

+                                the language specified by Language for the

+                                driver specified by This was returned in

+                                DriverName.

+

+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.

+

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  EFI_HANDLE                   ControllerHandle,

+  IN  EFI_HANDLE                   ChildHandle        OPTIONAL,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **ControllerName

+  )

+{

+  return EFI_UNSUPPORTED;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.c b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.c
new file mode 100644
index 0000000..7b1ab1c
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.c
@@ -0,0 +1,359 @@
+/** @file

+  ISA ACPI Protocol Implementation

+

+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+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.             

+**/

+

+#include "PcatIsaAcpi.h"

+

+//

+// Platform specific data for the ISA devices that are present.in the platform

+//

+

+//

+// COM 1 UART Controller

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiCom1DeviceResources[] = {

+  {EfiIsaAcpiResourceIo,        0, 0x3f8, 0x3ff},

+  {EfiIsaAcpiResourceInterrupt, 0, 4,     0},

+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}

+};

+

+//

+// COM 2 UART Controller

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiCom2DeviceResources[] = {

+  {EfiIsaAcpiResourceIo,        0, 0x2f8, 0x2ff},

+  {EfiIsaAcpiResourceInterrupt, 0, 3,     0},

+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}

+};

+

+//

+// PS/2 Keyboard Controller

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE  mPcatIsaAcpiPs2KeyboardDeviceResources[] = {

+  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},

+  {EfiIsaAcpiResourceInterrupt, 0, 1,     0},

+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}

+};

+

+//

+// PS/2 Mouse Controller

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE  mPcatIsaAcpiPs2MouseDeviceResources[] = {

+  {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},

+  {EfiIsaAcpiResourceInterrupt, 0, 12,     0},

+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}

+};

+

+//

+// Floppy Disk Controller

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiFloppyResources[] = {

+  {EfiIsaAcpiResourceIo,        0, 0x3f0, 0x3f7},

+  {EfiIsaAcpiResourceInterrupt, 0, 6,     0},

+  {EfiIsaAcpiResourceDma,       EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE | EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 | EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE, 2,     0},

+  {EfiIsaAcpiResourceEndOfList, 0, 0,     0}

+};

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiCom1Device = {

+  {EISA_PNP_ID(0x501), 0}, mPcatIsaAcpiCom1DeviceResources

+}; // COM 1 UART Controller

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiCom2Device = {

+  {EISA_PNP_ID(0x501), 1}, mPcatIsaAcpiCom2DeviceResources

+}; // COM 2 UART Controller

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiPs2KeyboardDevice = {

+  {EISA_PNP_ID(0x303), 0}, mPcatIsaAcpiPs2KeyboardDeviceResources

+}; // PS/2 Keyboard Controller

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiPs2MouseDevice = {

+  {EISA_PNP_ID(0x303), 1}, mPcatIsaAcpiPs2MouseDeviceResources

+}; // PS/2 Mouse Controller

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiFloppyADevice = {

+  {EISA_PNP_ID(0x604), 0}, mPcatIsaAcpiFloppyResources

+}; // Floppy Disk Controller A:

+

+GLOBAL_REMOVE_IF_UNREFERENCED

+EFI_ISA_ACPI_RESOURCE_LIST mPcatIsaAcpiFloppyBDevice = {

+  {EISA_PNP_ID(0x604), 1}, mPcatIsaAcpiFloppyResources

+}; // Floppy Disk Controller B:

+

+//

+// Table of ISA Controllers

+//

+EFI_ISA_ACPI_RESOURCE_LIST gPcatIsaAcpiDeviceList[7] = {{{0, 0}, NULL}};

+

+/**

+  Initialize gPcatIsaAcpiDeviceList.

+**/

+VOID

+InitializePcatIsaAcpiDeviceList (

+  VOID

+  )

+{

+  UINTN  Index;

+

+  Index = 0;

+  if (PcdGetBool (PcdIsaAcpiCom1Enable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiCom1Device, sizeof(mPcatIsaAcpiCom1Device));

+    Index++;

+  }

+  if (PcdGetBool (PcdIsaAcpiCom2Enable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiCom2Device, sizeof(mPcatIsaAcpiCom2Device));

+    Index++;

+  }

+  if (PcdGetBool (PcdIsaAcpiPs2KeyboardEnable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiPs2KeyboardDevice, sizeof(mPcatIsaAcpiPs2KeyboardDevice));

+    Index++;

+  }

+  if (PcdGetBool (PcdIsaAcpiPs2MouseEnable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiPs2MouseDevice, sizeof(mPcatIsaAcpiPs2MouseDevice));

+    Index++;

+  }

+  if (PcdGetBool (PcdIsaAcpiFloppyAEnable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiFloppyADevice, sizeof(mPcatIsaAcpiFloppyADevice));

+    Index++;

+  }

+  if (PcdGetBool (PcdIsaAcpiFloppyBEnable)) {

+    CopyMem (&gPcatIsaAcpiDeviceList[Index], &mPcatIsaAcpiFloppyBDevice, sizeof(mPcatIsaAcpiFloppyBDevice));

+    Index++;

+  }

+}

+

+//

+// ISA ACPI Protocol Functions

+//

+/**

+  Enumerate the ISA devices on the ISA bus.

+

+  @param Device             Point to device ID instance 

+  @param IsaAcpiDevice      On return, point to resource data for Isa device

+  @param NextIsaAcpiDevice  On return, point to resource data for next Isa device

+**/

+VOID

+IsaDeviceLookup (

+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **IsaAcpiDevice,

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **NextIsaAcpiDevice

+  )

+{

+  UINTN  Index;

+

+  *IsaAcpiDevice = NULL;

+  if (NextIsaAcpiDevice != NULL) {

+    *NextIsaAcpiDevice = NULL;

+  }

+  if (Device == NULL) {

+    Index = 0;

+  } else {

+    for(Index = 0; gPcatIsaAcpiDeviceList[Index].ResourceItem != NULL; Index++) {

+      if (Device->HID == gPcatIsaAcpiDeviceList[Index].Device.HID && 

+          Device->UID == gPcatIsaAcpiDeviceList[Index].Device.UID    ) {

+        break;

+      }

+    }

+    if (gPcatIsaAcpiDeviceList[Index].ResourceItem == NULL) {

+      return;

+    }

+    *IsaAcpiDevice = &(gPcatIsaAcpiDeviceList[Index]);

+    Index++;

+  }

+  if (gPcatIsaAcpiDeviceList[Index].ResourceItem != NULL && NextIsaAcpiDevice != NULL) {

+    *NextIsaAcpiDevice = &(gPcatIsaAcpiDeviceList[Index]);

+  }

+}

+

+/**

+  Enumerate the ISA devices on the ISA bus

+

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+

+  @retval EFI_NOT_FOUND Can not found the next Isa device.

+  @retval EFI_SUCESS    Success retrieve the next Isa device for enumration.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaDeviceEnumerate (

+  IN  EFI_ISA_ACPI_PROTOCOL   *This,

+  OUT EFI_ISA_ACPI_DEVICE_ID  **Device

+  )

+{

+  EFI_ISA_ACPI_RESOURCE_LIST  *IsaAcpiDevice;

+  EFI_ISA_ACPI_RESOURCE_LIST  *NextIsaAcpiDevice;

+

+  IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice);

+  if (NextIsaAcpiDevice == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  *Device = &(NextIsaAcpiDevice->Device);

+  return EFI_SUCCESS;

+}

+

+/**

+  Set ISA device power

+

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param OnOff           TRUE for setting isa device power on,

+                         FALSE for setting isa device power off

+

+  @return EFI_SUCCESS    Sucess to change power status for isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaDeviceSetPower (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device,

+  IN BOOLEAN                 OnOff

+  )

+{

+  return EFI_SUCCESS;

+} 

+

+/**

+  Get current resource for the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    On return, point to resources instances for given isa device

+

+  @retval EFI_NOT_FOUND Can not found the resource instance for given isa device

+  @retval EFI_SUCCESS   Success to get resource instance for given isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaGetCurrentResource (

+  IN  EFI_ISA_ACPI_PROTOCOL       *This,

+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,  

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList

+  )

+{

+  IsaDeviceLookup (Device, ResourceList, NULL);

+  if (*ResourceList == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+  Get possible resource for the specific ISA device.

+  

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    On return, point to resources instances for given isa device

+

+  @retval EFI_SUCCESS   Success to get resource instance for given isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaGetPossibleResource (

+  IN  EFI_ISA_ACPI_PROTOCOL       *This,

+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,  

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  Set resource for the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    Point to resources instances for given isa device

+

+  @return EFI_SUCESS  Success to set resource.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaSetResource (

+  IN EFI_ISA_ACPI_PROTOCOL       *This,

+  IN EFI_ISA_ACPI_DEVICE_ID      *Device,  

+  IN EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList

+  )

+{

+  return EFI_SUCCESS;

+}

+        

+/**

+  Enable/Disable the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param Enable          Enable/Disable

+

+  @return EFI_SUCESS  Success to enable/disable.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaEnableDevice (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device,

+  IN BOOLEAN                 Enable

+  )

+{

+  return EFI_SUCCESS;  

+}

+

+/**

+  Initialize the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+

+  @return EFI_SUCESS  Success to initialize.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaInitDevice (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device

+  )

+{

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Initialize the ISA interface.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+

+  @return EFI_SUCESS  Success to initialize ISA interface.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaInterfaceInit (

+  IN EFI_ISA_ACPI_PROTOCOL  *This

+)  

+{

+  return EFI_SUCCESS;

+}  

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
new file mode 100644
index 0000000..ef710b3
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
@@ -0,0 +1,56 @@
+## @file

+# IsaAcpi driver to install EFI_ISA_ACPI_PROTOCOL.

+#

+# Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>

+# 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = IsaAcpi

+  MODULE_UNI_FILE                = IsaAcpi.uni

+  FILE_GUID                      = 38A0EC22-FBE7-4911-8BC1-176E0D6C1DBD

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = PcatIsaAcpiDriverEntryPoint

+

+[Packages]

+  MdePkg/MdePkg.dec

+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+

+[LibraryClasses]

+  UefiDriverEntryPoint

+  UefiBootServicesTableLib

+  UefiLib

+  BaseMemoryLib

+  PcdLib

+

+[Sources]

+  PcatIsaAcpi.h

+  PcatIsaAcpi.c

+  IsaAcpi.c

+  ComponentName.c

+

+[Protocols]

+  gEfiPciIoProtocolGuid     ## TO_START

+  gEfiIsaAcpiProtocolGuid   ## BY_START

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable        ## SOMETIMES_CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable        ## SOMETIMES_CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable ## SOMETIMES_CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable    ## SOMETIMES_CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable     ## SOMETIMES_CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable     ## SOMETIMES_CONSUMES

+[UserExtensions.TianoCore."ExtraFiles"]

+  IsaAcpiExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.uni b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.uni
new file mode 100644
index 0000000..5aaf436
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpiExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpiExtra.uni
new file mode 100644
index 0000000..f5f7325
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/IsaAcpiExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.c b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.c
new file mode 100644
index 0000000..2b5ba6c
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.c
@@ -0,0 +1,389 @@
+/** @file

+  EFI PCAT ISA ACPI Driver for a Generic PC Platform

+

+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+#include "PcatIsaAcpi.h"

+

+//

+//  PcatIsaAcpi Driver Binding Protocol

+//

+EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding = {

+  PcatIsaAcpiDriverBindingSupported,

+  PcatIsaAcpiDriverBindingStart,

+  PcatIsaAcpiDriverBindingStop,

+  0xa,

+  NULL,

+  NULL

+};

+

+/**

+  the entry point of the PcatIsaAcpi driver.

+

+  @param ImageHandle     Handle for driver image

+  @param SystemTable     Point to EFI_SYSTEM_TABLE

+

+  @return Sucess or not for installing driver binding protocol

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return EfiLibInstallDriverBindingComponentName2 (

+           ImageHandle, 

+           SystemTable, 

+           &gPcatIsaAcpiDriverBinding,

+           ImageHandle,

+           &gPcatIsaAcpiComponentName,

+           &gPcatIsaAcpiComponentName2

+           );

+}

+

+/**

+  ControllerDriver Protocol Method

+

+  @param This                 Driver Binding protocol instance pointer.   

+  @param Controller           Handle of device to test.

+  @param RemainingDevicePath  Optional parameter use to pick a specific child

+                              device to start.

+  @retval EFI_SUCCESS         This driver supports this device.

+  @retval other               This driver does not support this device.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+{

+  EFI_STATUS           Status;

+  EFI_PCI_IO_PROTOCOL  *PciIo;

+  PCI_TYPE00           Pci;

+  UINTN                SegmentNumber;

+  UINTN                BusNumber;

+  UINTN                DeviceNumber;

+  UINTN                FunctionNumber;

+

+  //

+  // Get PciIo protocol instance

+  //              

+  Status = gBS->OpenProtocol (

+                  Controller,  

+                  &gEfiPciIoProtocolGuid, 

+                  (VOID**)&PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  Status = PciIo->Pci.Read (

+                    PciIo,

+                    EfiPciIoWidthUint32,

+                    0,

+                    sizeof(Pci) / sizeof(UINT32), 

+                    &Pci);

+

+  if (!EFI_ERROR (Status)) {

+    Status = EFI_UNSUPPORTED;

+    if ((Pci.Hdr.Command & 0x03) == 0x03) {

+      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {

+        //

+        // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code

+        //

+        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {

+          Status = EFI_SUCCESS;

+        } 

+

+        //

+        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode

+        //

+        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE && 

+            Pci.Hdr.VendorId     == 0x8086                          ) {

+          //

+          // See if this is on Function #0 to avoid false positives on 

+          // PCI_CLASS_BRIDGE_OTHER that has the same value as 

+          // PCI_CLASS_BRIDGE_ISA_PDECODE

+          //

+          Status = PciIo->GetLocation (

+                            PciIo, 

+                            &SegmentNumber, 

+                            &BusNumber, 

+                            &DeviceNumber, 

+                            &FunctionNumber

+                            );

+          if (!EFI_ERROR (Status) && FunctionNumber == 0) {

+            Status = EFI_SUCCESS;

+          } else {

+            Status = EFI_UNSUPPORTED;

+          }

+        }

+      } 

+    }

+  }

+

+  gBS->CloseProtocol (

+         Controller,       

+         &gEfiPciIoProtocolGuid, 

+         This->DriverBindingHandle,   

+         Controller   

+         );

+  

+  return Status;

+}

+

+/**

+  Install EFI_ISA_ACPI_PROTOCOL.

+

+  @param  This                 Driver Binding protocol instance pointer.

+  @param  ControllerHandle     Handle of device to bind driver to.

+  @param  RemainingDevicePath  Optional parameter use to pick a specific child

+                               device to start.

+

+  @retval EFI_SUCCESS          This driver is added to ControllerHandle

+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle

+  @retval other                This driver does not support this device

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+{

+  EFI_STATUS           Status;

+  EFI_PCI_IO_PROTOCOL  *PciIo;

+  PCAT_ISA_ACPI_DEV    *PcatIsaAcpiDev;

+  UINT64               Supports;

+  BOOLEAN              Enabled;

+

+  Enabled = FALSE;

+  Supports = 0;

+  PcatIsaAcpiDev = NULL;

+  //

+  // Open the PCI I/O Protocol Interface

+  //

+  PciIo = NULL;

+  Status = gBS->OpenProtocol (

+                  Controller,       

+                  &gEfiPciIoProtocolGuid, 

+                  (VOID**)&PciIo,

+                  This->DriverBindingHandle,   

+                  Controller,   

+                  EFI_OPEN_PROTOCOL_BY_DRIVER 

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Get supported PCI attributes

+  //

+  Status = PciIo->Attributes (

+                    PciIo,

+                    EfiPciIoAttributeOperationSupported,

+                    0,

+                    &Supports

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);

+  if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {

+    Status = EFI_UNSUPPORTED;

+    goto Done;

+  }  

+

+  Enabled = TRUE;

+  Status = PciIo->Attributes (

+                    PciIo, 

+                    EfiPciIoAttributeOperationEnable, 

+                    EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO, 

+                    NULL 

+                    );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+  

+  //

+  // Allocate memory for the PCAT ISA ACPI Device structure

+  //

+  PcatIsaAcpiDev = NULL;

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof(PCAT_ISA_ACPI_DEV),

+                  (VOID**)&PcatIsaAcpiDev

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  //

+  // Initialize the PCAT ISA ACPI Device structure

+  //

+  PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;

+  PcatIsaAcpiDev->Handle    = Controller;

+  PcatIsaAcpiDev->PciIo     = PciIo;

+

+  //

+  // Initialize PcatIsaAcpiDeviceList

+  //

+  InitializePcatIsaAcpiDeviceList ();

+  

+  //

+  // IsaAcpi interface

+  //

+  (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate  = IsaDeviceEnumerate;

+  (PcatIsaAcpiDev->IsaAcpi).SetPower         = IsaDeviceSetPower;

+  (PcatIsaAcpiDev->IsaAcpi).GetCurResource   = IsaGetCurrentResource;

+  (PcatIsaAcpiDev->IsaAcpi).GetPosResource   = IsaGetPossibleResource;

+  (PcatIsaAcpiDev->IsaAcpi).SetResource      = IsaSetResource;

+  (PcatIsaAcpiDev->IsaAcpi).EnableDevice     = IsaEnableDevice;

+  (PcatIsaAcpiDev->IsaAcpi).InitDevice       = IsaInitDevice;

+  (PcatIsaAcpiDev->IsaAcpi).InterfaceInit    = IsaInterfaceInit;

+    

+  //

+  // Install the ISA ACPI Protocol interface

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Controller,

+                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,

+                  NULL

+                  );

+

+Done:

+  if (EFI_ERROR (Status)) {

+    if (PciIo != NULL && Enabled) {

+      PciIo->Attributes (

+               PciIo, 

+               EfiPciIoAttributeOperationDisable, 

+               EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,

+               NULL 

+               );

+    }

+    gBS->CloseProtocol (

+           Controller, 

+           &gEfiPciIoProtocolGuid, 

+           This->DriverBindingHandle, 

+           Controller

+           );

+    if (PcatIsaAcpiDev != NULL) {

+      gBS->FreePool (PcatIsaAcpiDev);

+    }

+    return Status;

+  }

+          

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Stop this driver on ControllerHandle. Support stopping any child handles

+  created by this driver.

+

+  @param  This              Protocol instance pointer.

+  @param  ControllerHandle  Handle of device to stop driver on

+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of

+                            children is zero stop the entire bus driver.

+  @param  ChildHandleBuffer List of Child Handles to Stop.

+

+  @retval EFI_SUCCESS       This driver is removed ControllerHandle

+  @retval other             This driver was not removed from this device

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN UINTN                        NumberOfChildren,

+  IN EFI_HANDLE                   *ChildHandleBuffer

+  )

+{

+  EFI_STATUS             Status;

+  EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;

+  PCAT_ISA_ACPI_DEV      *PcatIsaAcpiDev;

+  UINT64                 Supports;

+  

+  //

+  // Get the ISA ACPI Protocol Interface

+  // 

+  Status = gBS->OpenProtocol (

+                  Controller, 

+                  &gEfiIsaAcpiProtocolGuid, 

+                  (VOID**)&IsaAcpi,

+                  This->DriverBindingHandle,   

+                  Controller,   

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol

+  //

+  PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);

+

+  //

+  // Get supported PCI attributes

+  //

+  Status = PcatIsaAcpiDev->PciIo->Attributes (

+                                    PcatIsaAcpiDev->PciIo,

+                                    EfiPciIoAttributeOperationSupported,

+                                    0,

+                                    &Supports

+                                    );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);

+

+  PcatIsaAcpiDev->PciIo->Attributes (

+                           PcatIsaAcpiDev->PciIo, 

+                           EfiPciIoAttributeOperationDisable, 

+                           EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,

+                           NULL 

+                           );

+ 

+  //

+  // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL

+  //

+  Status = gBS->UninstallProtocolInterface (

+                  Controller,

+                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  gBS->CloseProtocol (

+         Controller, 

+         &gEfiPciIoProtocolGuid, 

+         This->DriverBindingHandle, 

+         Controller

+         );

+  

+  gBS->FreePool (PcatIsaAcpiDev);

+  

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.h b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.h
new file mode 100644
index 0000000..1fcac40
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.h
@@ -0,0 +1,274 @@
+/** @file

+  EFI PCAT ISA ACPI Driver for a Generic PC Platform

+

+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>

+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.             

+

+**/

+

+#ifndef _PCAT_ISA_ACPI_H_

+#define _PCAT_ISA_ACPI_H_

+

+#include <PiDxe.h>

+

+#include <IndustryStandard/Pci.h>

+

+#include <Protocol/DevicePath.h>

+#include <Protocol/PciIo.h>

+#include <Protocol/IsaIo.h>

+#include <Protocol/DriverBinding.h>

+#include <Protocol/ComponentName.h>

+#include <Protocol/ComponentName2.h>

+

+

+#include <Library/UefiLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/PcdLib.h>

+

+#include <Protocol/IsaAcpi.h>

+//

+// PCAT ISA ACPI device private data structure

+//

+#define PCAT_ISA_ACPI_DEV_SIGNATURE  SIGNATURE_32('L','P','C','D')

+

+typedef struct {

+  UINTN                  Signature;

+  EFI_HANDLE             Handle;    

+  EFI_ISA_ACPI_PROTOCOL  IsaAcpi;

+  EFI_PCI_IO_PROTOCOL    *PciIo;

+} PCAT_ISA_ACPI_DEV;

+

+#define PCAT_ISA_ACPI_DEV_FROM_THIS(a) BASE_CR(a, PCAT_ISA_ACPI_DEV, IsaAcpi)

+

+//

+// Global Variables

+//

+extern EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding;

+

+extern EFI_COMPONENT_NAME2_PROTOCOL gPcatIsaAcpiComponentName2;

+

+extern EFI_COMPONENT_NAME_PROTOCOL  gPcatIsaAcpiComponentName;

+

+

+//

+// Prototypes for Driver model protocol interface

+//

+/**

+  ControllerDriver Protocol Method

+

+  @param This                 Driver Binding protocol instance pointer.   

+  @param Controller           Handle of device to test.

+  @param RemainingDevicePath  Optional parameter use to pick a specific child

+                              device to start.

+  @retval EFI_SUCCESS         This driver supports this device.

+  @retval other               This driver does not support this device.

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+/**

+  Install EFI_ISA_ACPI_PROTOCOL.

+

+  @param  This                 Driver Binding protocol instance pointer.

+  @param  ControllerHandle     Handle of device to bind driver to.

+  @param  RemainingDevicePath  Optional parameter use to pick a specific child

+                               device to start.

+

+  @retval EFI_SUCCESS          This driver is added to ControllerHandle

+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle

+  @retval other                This driver does not support this device

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  );

+

+/**

+  Stop this driver on ControllerHandle. Support stopping any child handles

+  created by this driver.

+

+  @param  This              Protocol instance pointer.

+  @param  ControllerHandle  Handle of device to stop driver on

+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of

+                            children is zero stop the entire bus driver.

+  @param  ChildHandleBuffer List of Child Handles to Stop.

+

+  @retval EFI_SUCCESS       This driver is removed ControllerHandle

+  @retval other             This driver was not removed from this device

+

+**/

+EFI_STATUS

+EFIAPI

+PcatIsaAcpiDriverBindingStop (

+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN  EFI_HANDLE                   Controller,

+  IN  UINTN                        NumberOfChildren,

+  IN  EFI_HANDLE                   *ChildHandleBuffer

+  );

+

+//

+// Prototypes for the ISA ACPI protocol interface

+//

+/**

+  Enumerate the ISA devices on the ISA bus

+

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+

+  @retval EFI_NOT_FOUND Can not found the next Isa device.

+  @retval EFI_SUCESS    Success retrieve the next Isa device for enumration.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaDeviceEnumerate (

+  IN  EFI_ISA_ACPI_PROTOCOL   *This,

+  OUT EFI_ISA_ACPI_DEVICE_ID  **Device

+  );

+

+/**

+  Set ISA device power

+

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param OnOff           TRUE for setting isa device power on,

+                         FALSE for setting isa device power off

+

+  @return EFI_SUCCESS    Sucess to change power status for isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaDeviceSetPower (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device,

+  IN BOOLEAN                 OnOff

+  );

+  

+/**

+  Get current resource for the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    On return, point to resources instances for given isa device

+

+  @retval EFI_NOT_FOUND Can not found the resource instance for given isa device

+  @retval EFI_SUCCESS   Success to get resource instance for given isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaGetCurrentResource (

+  IN  EFI_ISA_ACPI_PROTOCOL       *This,

+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList

+  );

+  

+/**

+  Get possible resource for the specific ISA device.

+  

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    On return, point to resources instances for given isa device

+

+  @retval EFI_SUCCESS   Success to get resource instance for given isa device.

+**/

+EFI_STATUS

+EFIAPI

+IsaGetPossibleResource (

+  IN  EFI_ISA_ACPI_PROTOCOL       *This,

+  IN  EFI_ISA_ACPI_DEVICE_ID      *Device,  

+  OUT EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList

+  );

+  

+/**

+  Set resource for the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param ResourceList    Point to resources instances for given isa device

+

+  @return EFI_SUCESS  Success to set resource.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaSetResource (

+  IN EFI_ISA_ACPI_PROTOCOL       *This,

+  IN EFI_ISA_ACPI_DEVICE_ID      *Device,

+  IN EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList

+  );

+  

+/**

+  Enable/Disable the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+  @param Enable          Enable/Disable

+

+  @return EFI_SUCESS  Success to enable/disable.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaEnableDevice (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device,

+  IN BOOLEAN                 Enable

+  );

+

+/**

+  Initialize the specific ISA device.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+  @param Device          Point to device ID instance 

+

+  @return EFI_SUCESS  Success to initialize.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaInitDevice (

+  IN EFI_ISA_ACPI_PROTOCOL   *This,

+  IN EFI_ISA_ACPI_DEVICE_ID  *Device

+  );

+  

+/**

+  Initialize the ISA interface.

+

+  @param This            Point to instance of EFI_ISA_ACPI_PROTOCOL

+

+  @return EFI_SUCESS  Success to initialize ISA interface.

+

+**/

+EFI_STATUS

+EFIAPI

+IsaInterfaceInit (

+  IN EFI_ISA_ACPI_PROTOCOL  *This

+  );  

+

+/**

+  Initialize the ISA device list.

+**/

+VOID

+InitializePcatIsaAcpiDeviceList (

+  VOID

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcReset.uni b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcReset.uni
new file mode 100644
index 0000000..7c1591f
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcReset.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcResetExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcResetExtra.uni
new file mode 100644
index 0000000..678cb5b
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/KbcResetExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/Reset.inf b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/Reset.inf
new file mode 100644
index 0000000..b54b08c
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/Reset.inf
@@ -0,0 +1,50 @@
+## @file

+# This driver implements Reset Architectural Protocol.

+#

+# It should depend on the ResetSystemLib instance that is implemented based on KBC.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+# 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:

+#    Reset.inf

+#

+#  Abstract:

+#

+##

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = KbcReset

+  MODULE_UNI_FILE                = KbcReset.uni

+  FILE_GUID                      = 6F0198AA-1F1D-426D-AE3E-39AB633FCC28

+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = InitializeReset

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+

+[LibraryClasses]

+  UefiDriverEntryPoint

+  DebugLib

+  UefiBootServicesTableLib

+  ResetSystemLib

+

+[Sources]

+  ResetEntry.c

+

+[Protocols]

+  gEfiResetArchProtocolGuid ## PRODUCES

+

+[Depex]

+  TRUE

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  KbcResetExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/ResetEntry.c b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/ResetEntry.c
new file mode 100644
index 0000000..03b4250
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/KbcResetDxe/ResetEntry.c
@@ -0,0 +1,106 @@
+/** @file

+  Driver entry for KbcReset driver.

+

+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

+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.             

+**/

+

+#include <PiDxe.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/ResetSystemLib.h>

+

+#include <Protocol/Reset.h>

+

+//

+// The handle onto which the Reset Architectural Protocol is installed

+//

+EFI_HANDLE  mResetHandle = NULL;

+

+/**

+  Reset the system.

+

+  @param ResetType       warm or cold

+  @param ResetStatus     possible cause of reset

+  @param DataSize        Size of ResetData in bytes

+  @param ResetData       Optional Unicode string

+

+**/

+VOID

+EFIAPI

+KbcResetSystem (

+  IN EFI_RESET_TYPE   ResetType,

+  IN EFI_STATUS       ResetStatus,

+  IN UINTN            DataSize,

+  IN VOID             *ResetData OPTIONAL

+  )

+{

+  switch (ResetType) {

+  case EfiResetWarm:

+    ResetWarm ();

+    break;

+  case EfiResetCold:

+    ResetCold ();

+    break;

+  case EfiResetShutdown:

+    ResetShutdown ();

+    break;

+  default:

+    return;

+  }

+

+  //

+  // Given we should have reset getting here would be bad

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Initialize the state information for the Reset Architectural Protocol.

+

+  @param ImageHandle     Handle of the loaded driver 

+  @param SystemTable     Pointer to the System Table

+

+  @retval EFI_SUCCESS           Thread can be successfully created

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Cannot create the timer service

+

+**/

+EFI_STATUS

+EFIAPI

+InitializeReset (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Make sure the Reset Architectural Protocol is not already installed in the system

+  //

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);

+

+  //

+  // Hook the runtime service table

+  //

+  SystemTable->RuntimeServices->ResetSystem = KbcResetSystem;

+

+  //

+  // Now install the Reset RT AP on a new handle

+  //

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mResetHandle,

+                  &gEfiResetArchProtocolGuid, NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c
new file mode 100644
index 0000000..b184c49
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -0,0 +1,337 @@
+/** @file

+  ACPI Timer implements one instance of Timer Library.

+

+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PciLib.h>

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <IndustryStandard/Acpi.h>

+

+/**

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+InternalGetPerformanceCounterFrequency (

+  VOID

+  );

+

+/**

+  The constructor function enables ACPI IO space.

+

+  If ACPI I/O space not enabled, this function will enable it.

+  It will always return RETURN_SUCCESS.

+

+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.

+

+**/

+RETURN_STATUS

+EFIAPI

+AcpiTimerLibConstructor (

+  VOID

+  )

+{

+  UINTN   Bus;

+  UINTN   Device;

+  UINTN   Function;

+  UINTN   EnableRegister;

+  UINT8   EnableMask;

+

+  //

+  // ASSERT for the invalid PCD values. They must be configured to the real value. 

+  //

+  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);

+  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);

+

+  //

+  // If the register offset to the BAR for the ACPI I/O Port Base Address is 0x0000, then 

+  // no PCI register programming is required to enable access to the the ACPI registers

+  // specified by PcdAcpiIoPortBaseAddress

+  //

+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {

+    return RETURN_SUCCESS;

+  }

+

+  //

+  // ASSERT for the invalid PCD values. They must be configured to the real value. 

+  //

+  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);

+  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);

+  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);

+

+  //

+  // Retrieve the PCD values for the PCI configuration space required to program the ACPI I/O Port Base Address

+  //

+  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);

+  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);

+  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);

+  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);

+  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);

+

+  //

+  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it.

+  //

+  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister) & EnableMask) != EnableMask)) {

+    PciWrite16 (

+      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarRegisterOffset)),

+      PcdGet16 (PcdAcpiIoPortBaseAddress)

+      );

+    PciOr8 (

+      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),

+      EnableMask

+      );

+  }

+  

+  return RETURN_SUCCESS;

+}

+

+/**

+  Internal function to retrieve the ACPI I/O Port Base Address.

+

+  Internal function to retrieve the ACPI I/O Port Base Address.

+

+  @return The 16-bit ACPI I/O Port Base Address.

+

+**/

+UINT16

+InternalAcpiGetAcpiTimerIoPort (

+  VOID

+  )

+{

+  UINT16  Port;

+  

+  Port = PcdGet16 (PcdAcpiIoPciBarRegisterOffset);

+  

+  //

+  // If the register offset to the BAR for the ACPI I/O Port Base Address is not 0x0000, then 

+  // read the PCI register for the APCI BAR value in case the BAR has been programmed to a 

+  // value other than PcdAcpiIoPortBaseAddress

+  //

+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {

+    Port = PciRead16 (PCI_LIB_ADDRESS (

+                        PcdGet8  (PcdAcpiIoPciBusNumber), 

+                        PcdGet8  (PcdAcpiIoPciDeviceNumber), 

+                        PcdGet8  (PcdAcpiIoPciFunctionNumber), 

+                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)

+                        ));

+  }

+  

+  return (Port & ~BIT0) + PcdGet16 (PcdAcpiPm1TmrOffset);

+}

+

+/**

+  Stalls the CPU for at least the given number of ticks.

+

+  Stalls the CPU for at least the given number of ticks. It's invoked by

+  MicroSecondDelay() and NanoSecondDelay().

+

+  @param  Delay     A period of time to delay in ticks.

+

+**/

+VOID

+InternalAcpiDelay (

+  IN UINT32  Delay

+  )

+{

+  UINT16   Port;

+  UINT32   Ticks;

+  UINT32   Times;

+

+  Port   = InternalAcpiGetAcpiTimerIoPort ();

+  Times  = Delay >> 22;

+  Delay &= BIT22 - 1;

+  do {

+    //

+    // The target timer count is calculated here

+    //

+    Ticks = IoRead32 (Port) + Delay;

+    Delay = BIT22;

+    //

+    // Wait until time out

+    // Delay >= 2^23 could not be handled by this function

+    // Timer wrap-arounds are handled correctly by this function

+    //

+    while (((Ticks - IoRead32 (Port)) & BIT23) == 0) {

+      CpuPause ();

+    }

+  } while (Times-- > 0);

+}

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return MicroSeconds

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN UINTN  MicroSeconds

+  )

+{

+  InternalAcpiDelay (

+    (UINT32)DivU64x32 (

+              MultU64x32 (

+                MicroSeconds,

+                ACPI_TIMER_FREQUENCY

+                ),

+              1000000u

+              )

+    );

+  return MicroSeconds;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return NanoSeconds

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN UINTN  NanoSeconds

+  )

+{

+  InternalAcpiDelay (

+    (UINT32)DivU64x32 (

+              MultU64x32 (

+                NanoSeconds,

+                ACPI_TIMER_FREQUENCY

+                ),

+              1000000000u

+              )

+    );

+  return NanoSeconds;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return AsmReadTsc ();

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT UINT64  *StartValue,  OPTIONAL

+  OUT UINT64  *EndValue     OPTIONAL

+  )

+{

+  if (StartValue != NULL) {

+    *StartValue = 0;

+  }

+

+  if (EndValue != NULL) {

+    *EndValue = 0xffffffffffffffffULL;

+  }

+  return InternalGetPerformanceCounterFrequency ();

+}

+

+/**

+  Converts elapsed ticks of performance counter to time in nanoseconds.

+

+  This function converts the elapsed ticks of running performance counter to

+  time value in unit of nanoseconds.

+

+  @param  Ticks     The number of elapsed ticks of running performance counter.

+

+  @return The elapsed time in nanoseconds.

+

+**/

+UINT64

+EFIAPI

+GetTimeInNanoSecond (

+  IN UINT64  Ticks

+  )

+{

+  UINT64  Frequency;

+  UINT64  NanoSeconds;

+  UINT64  Remainder;

+  INTN    Shift;

+

+  Frequency = GetPerformanceCounterProperties (NULL, NULL);

+

+  //

+  //          Ticks

+  // Time = --------- x 1,000,000,000

+  //        Frequency

+  //

+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);

+

+  //

+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.

+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,

+  // i.e. highest bit set in Remainder should <= 33.

+  //

+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);

+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);

+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);

+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);

+

+  return NanoSeconds;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
new file mode 100644
index 0000000..21fdb79
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
@@ -0,0 +1,42 @@
+/** @file

+  ACPI Timer implements one instance of Timer Library.

+

+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+

+/**

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+InternalGetPerformanceCounterFrequency (

+  VOID

+  ) 

+{

+  BOOLEAN  InterruptState;

+  UINT64   Count;

+  UINT64   Frequency;

+  

+  InterruptState = SaveAndDisableInterrupts ();

+  Count = GetPerformanceCounter ();

+  MicroSecondDelay (100);

+  Frequency = MultU64x32 (GetPerformanceCounter () - Count, 10000);

+  SetInterruptState (InterruptState);

+  return Frequency;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
new file mode 100644
index 0000000..fcd7814
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
@@ -0,0 +1,51 @@
+## @file

+#  Base ACPI Timer Library

+#

+#  Provides basic timer support using the ACPI timer hardware.  The performance

+#  counter features are provided by the processors time stamp counter. 

+#

+#  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseAcpiTimerLib

+  FILE_GUID                      = 564DE85F-049E-4481-BF7A-CA04D2788CF9

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib|SEC PEI_CORE PEIM

+  CONSTRUCTOR                    = AcpiTimerLibConstructor

+  MODULE_UNI_FILE                = BaseAcpiTimerLib.uni

+

+[Sources]

+  AcpiTimerLib.c

+  BaseAcpiTimerLib.c

+  

+[Packages]

+  MdePkg/MdePkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PcdLib

+  PciLib

+  IoLib

+  DebugLib

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber             ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber          ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber        ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset  ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask            ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset     ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress          ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset               ## CONSUMES

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
new file mode 100644
index 0000000..a3d8f3c
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c
new file mode 100644
index 0000000..6f5c07a
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.c
@@ -0,0 +1,48 @@
+/** @file

+  ACPI Timer implements one instance of Timer Library.

+

+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+

+//

+// Cached performance counter frequency

+//

+UINT64  mPerformanceCounterFrequency = 0;

+

+/**

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  Internal function to retrieves the 64-bit frequency in Hz.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+InternalGetPerformanceCounterFrequency (

+  VOID

+  ) 

+{

+  BOOLEAN  InterruptState;

+  UINT64   Count;

+

+  if (mPerformanceCounterFrequency == 0) {

+    InterruptState = SaveAndDisableInterrupts ();

+    Count = GetPerformanceCounter ();

+    MicroSecondDelay (100);

+    mPerformanceCounterFrequency = MultU64x32 (GetPerformanceCounter () - Count, 10000);

+    SetInterruptState (InterruptState);

+  }

+  return  mPerformanceCounterFrequency;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
new file mode 100644
index 0000000..5c8a8e6
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
@@ -0,0 +1,51 @@
+## @file

+#  DXE ACPI Timer Library

+#

+#  Provides basic timer support using the ACPI timer hardware.  The performance

+#  counter features are provided by the processors time stamp counter. 

+#

+#  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeAcpiTimerLib

+  FILE_GUID                      = E624B98C-845A-4b94-9B50-B20475D552B9

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+  CONSTRUCTOR                    = AcpiTimerLibConstructor

+  MODULE_UNI_FILE                = DxeAcpiTimerLib.uni

+

+[Sources]

+  AcpiTimerLib.c

+  DxeAcpiTimerLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PcdLib

+  PciLib

+  IoLib

+  DebugLib

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber             ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber          ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber        ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset  ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask            ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset     ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress          ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset               ## CONSUMES

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.uni
new file mode 100644
index 0000000..d56eb31
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
new file mode 100644
index 0000000..f549f74
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
@@ -0,0 +1,40 @@
+## @file

+#  Library instance for I/O APIC library class

+#

+#  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseIoApicLib

+  MODULE_UNI_FILE                = BaseIoApicLib.uni

+  FILE_GUID                      = 58ED6E5A-E36A-462a-9ED6-6E62C9A26DF8

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoApicLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  UefiCpuPkg/UefiCpuPkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+

+[LibraryClasses]

+  DebugLib

+  IoLib

+  PcdLib

+  LocalApicLib

+

+[Sources]

+  IoApicLib.c

+

+[Pcd]

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress    ## CONSUMES

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni
new file mode 100644
index 0000000..15f2840
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c
new file mode 100644
index 0000000..42b3f21
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c
@@ -0,0 +1,158 @@
+/** @file 

+  I/O APIC library.

+

+  I/O APIC library assumes I/O APIC is enabled. It does not

+  handles cases where I/O APIC is disabled.

+

+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+

+#include <Library/IoApicLib.h>

+

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+#include <Library/LocalApicLib.h>

+

+#include <Register/IoApic.h>

+

+/**

+  Read a 32-bit I/O APIC register.

+

+  If Index is >= 0x100, then ASSERT().

+  

+  @param  Index  Specifies the I/O APIC register to read.

+

+  @return  The 32-bit value read from the I/O APIC register specified by Index.

+**/

+UINT32

+EFIAPI

+IoApicRead (

+  IN UINTN  Index

+  )

+{

+  ASSERT (Index < 0x100);

+  MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);

+  return MmioRead32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET);

+}

+

+/**

+  Write a 32-bit I/O APIC register.

+

+  If Index is >= 0x100, then ASSERT().

+  

+  @param  Index  Specifies the I/O APIC register to write.

+  @param  Value  Specifies the value to write to the I/O APIC register specified by Index.

+

+  @return  The 32-bit value written to I/O APIC register specified by Index.

+**/

+UINT32

+EFIAPI

+IoApicWrite (

+  IN UINTN   Index,

+  IN UINT32  Value

+  )

+{

+  ASSERT (Index < 0x100);

+  MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);

+  return MmioWrite32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET, Value);

+}

+

+/**

+  Set the interrupt mask of an I/O APIC interrupt.

+

+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). 

+

+  @param  Irq     Specifies the I/O APIC interrupt to enable or disable.

+  @param  Enable  If TRUE, then enable the I/O APIC interrupt specified by Irq.

+                  If FALSE, then disable the I/O APIC interrupt specified by Irq.

+**/

+VOID

+EFIAPI

+IoApicEnableInterrupt (

+  IN UINTN    Irq,

+  IN BOOLEAN  Enable

+  )

+{

+  IO_APIC_VERSION_REGISTER         Version;

+  IO_APIC_REDIRECTION_TABLE_ENTRY  Entry;

+

+  Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);

+  ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);

+  ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);

+

+  Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);

+  Entry.Bits.Mask = Enable ? 0 : 1;

+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);

+}

+

+/**

+  Configures an I/O APIC interrupt.

+  

+  Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical

+  mode to the Local APIC of the currntly executing CPU.  The default state of the 

+  entry is for the interrupt to be disabled (masked).  IoApicEnableInterrupts() must

+  be used to enable(unmask) the I/O APIC Interrupt.

+ 

+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). 

+  If Vector >= 0x100, then ASSERT().

+  If DeliveryMode is not supported, then ASSERT().

+

+  @param  Irq             Specifies the I/O APIC interrupt to initialize.

+  @param  Vector          The 8-bit interrupt vector associated with the I/O APIC

+                          Interrupt.  Must be in the range 0x10..0xFE.

+  @param  DeliveryMode    A 3-bit value that specifies how the recept of the I/O APIC

+                          interrupt is handled.  The only supported values are:

+                            0: IO_APIC_DELIVERY_MODE_FIXED

+                            1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY

+                            2: IO_APIC_DELIVERY_MODE_SMI

+                            4: IO_APIC_DELIVERY_MODE_NMI

+                            5: IO_APIC_DELIVERY_MODE_INIT

+                            7: IO_APIC_DELIVERY_MODE_EXTINT

+  @param  LevelTriggered  TRUE specifies a level triggered interrupt.

+                          FALSE specifies an edge triggered interrupt.

+  @param  AssertionLevel  TRUE specified an active high interrupt.

+                          FALSE specifies an active low interrupt.

+**/

+VOID

+EFIAPI

+IoApicConfigureInterrupt (

+  IN UINTN    Irq,

+  IN UINTN    Vector,

+  IN UINTN    DeliveryMode,

+  IN BOOLEAN  LevelTriggered,

+  IN BOOLEAN  AssertionLevel

+  )

+{

+  IO_APIC_VERSION_REGISTER         Version;

+  IO_APIC_REDIRECTION_TABLE_ENTRY  Entry;

+

+  Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);

+  ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);

+  ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);

+  ASSERT (Vector <= 0xFF);

+  ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);

+  

+  Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);

+  Entry.Bits.Vector          = (UINT8)Vector;

+  Entry.Bits.DeliveryMode    = (UINT32)DeliveryMode;

+  Entry.Bits.DestinationMode = 0; 

+  Entry.Bits.Polarity        = AssertionLevel ? 0 : 1;

+  Entry.Bits.TriggerMode     = LevelTriggered ? 1 : 0;

+  Entry.Bits.Mask            = 1;

+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);

+

+  Entry.Uint32.High = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1);

+  Entry.Bits.DestinationID = GetApicId ();

+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1, Entry.Uint32.High);

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000..6a9dd71
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,86 @@
+/** @file

+  Reset System Library functions for PCAT platforms

+

+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+

+/**

+  Calling this function causes a system-wide reset. This sets

+  all circuitry within the system to its initial state. This type of reset

+  is asynchronous to system operation and operates without regard to

+  cycle boundaries.

+

+  System reset should not return, if it returns, it means the system does

+  not support cold reset.

+**/

+VOID

+EFIAPI

+ResetCold (

+  VOID

+  )

+{

+  IoWrite8 (0x64, 0xfe);

+}

+

+/**

+  Calling this function causes a system-wide initialization. The processors

+  are set to their initial state, and pending cycles are not corrupted.

+

+  System reset should not return, if it returns, it means the system does

+  not support warm reset.

+**/

+VOID

+EFIAPI

+ResetWarm (

+  VOID

+  )

+{

+  IoWrite8 (0x64, 0xfe);

+}

+

+/**

+  Calling this function causes the system to enter a power state equivalent

+  to the ACPI G2/S5 or G3 states.

+

+  System shutdown should not return, if it returns, it means the system does

+  not support shut down reset.

+**/

+VOID

+EFIAPI

+ResetShutdown (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+

+/**

+  Calling this function causes the system to enter a power state for capsule

+  update.

+

+  Reset update should not return, if it returns, it means the system does

+  not support capsule update.

+

+**/

+VOID

+EFIAPI

+EnterS3WithImmediateWake (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000..c994827
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,39 @@
+## @file

+#   Library instance for ResetSystem library class for PCAT systems

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = ResetSystemLib

+  MODULE_UNI_FILE                = ResetSystemLib.uni

+  FILE_GUID                      = EC4F3E59-F879-418b-9E4C-7D6F434714A0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ResetSystemLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF

+#

+

+[Sources]

+  ResetSystemLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  IoLib

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.uni
new file mode 100644
index 0000000..79868be
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/PcAtSerialPortLib.uni b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/PcAtSerialPortLib.uni
new file mode 100644
index 0000000..decd83f
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/PcAtSerialPortLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
new file mode 100644
index 0000000..959d6e2
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
@@ -0,0 +1,33 @@
+## @file

+#   Library instance for SerialIo library class

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PcAtSerialPortLib

+  MODULE_UNI_FILE                = PcAtSerialPortLib.uni

+  FILE_GUID                      = 1B25AF84-1EA8-4b52-894E-BFA6880B97FF

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SerialPortLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  IoLib

+

+[Sources]

+  SerialPortLib.c

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c
new file mode 100644
index 0000000..6bf7053
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c
@@ -0,0 +1,221 @@
+/** @file

+  UART Serial Port library functions

+

+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/IoLib.h>

+#include <Library/SerialPortLib.h>

+

+//---------------------------------------------

+// UART Register Offsets

+//---------------------------------------------

+#define BAUD_LOW_OFFSET         0x00

+#define BAUD_HIGH_OFFSET        0x01

+#define IER_OFFSET              0x01

+#define LCR_SHADOW_OFFSET       0x01

+#define FCR_SHADOW_OFFSET       0x02

+#define IR_CONTROL_OFFSET       0x02

+#define FCR_OFFSET              0x02

+#define EIR_OFFSET              0x02

+#define BSR_OFFSET              0x03

+#define LCR_OFFSET              0x03

+#define MCR_OFFSET              0x04

+#define LSR_OFFSET              0x05

+#define MSR_OFFSET              0x06

+

+//---------------------------------------------

+// UART Register Bit Defines

+//---------------------------------------------

+#define LSR_TXRDY               0x20

+#define LSR_RXDA                0x01

+#define DLAB                    0x01

+

+//---------------------------------------------

+// UART Settings

+//---------------------------------------------

+UINT16  gUartBase = 0x3F8;

+UINTN   gBps      = 115200;

+UINT8   gData     = 8;

+UINT8   gStop     = 1;

+UINT8   gParity   = 0;

+UINT8   gBreakSet = 0;

+

+/**

+  Initialize the serial device hardware.

+  

+  If no initialization is required, then return RETURN_SUCCESS.

+  If the serial device was successfuly initialized, then return RETURN_SUCCESS.

+  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.

+  

+  @retval RETURN_SUCCESS        The serial device was initialized.

+  @retval RETURN_DEVICE_ERROR   The serail device could not be initialized.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortInitialize (

+  VOID

+  )

+{

+  UINTN  Divisor;

+  UINT8  OutputData;

+  UINT8  Data;

+

+  //

+  // Map 5..8 to 0..3

+  //

+  Data = (UINT8) (gData - (UINT8) 5);

+

+  //

+  // Calculate divisor for baud generator

+  //

+  Divisor = 115200 / gBps;

+  

+  //

+  // Set communications format

+  //

+  OutputData = (UINT8) ((DLAB << 7) | (gBreakSet << 6) | (gParity << 3) | (gStop << 2) | Data);

+  IoWrite8 ((UINTN) (gUartBase + LCR_OFFSET), OutputData);

+

+  //

+  // Configure baud rate

+  //

+  IoWrite8 ((UINTN) (gUartBase + BAUD_HIGH_OFFSET), (UINT8) (Divisor >> 8));

+  IoWrite8 ((UINTN) (gUartBase + BAUD_LOW_OFFSET), (UINT8) (Divisor & 0xff));

+

+  //

+  // Switch back to bank 0

+  //

+  OutputData = (UINT8) ((~DLAB << 7) | (gBreakSet << 6) | (gParity << 3) | (gStop << 2) | Data);

+  IoWrite8 ((UINTN) (gUartBase + LCR_OFFSET), OutputData);

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Write data from buffer to serial device. 

+ 

+  Writes NumberOfBytes data bytes from Buffer to the serial device.  

+  The number of bytes actually written to the serial device is returned.

+  If the return value is less than NumberOfBytes, then the write operation failed.

+

+  If Buffer is NULL, then ASSERT(). 

+

+  If NumberOfBytes is zero, then return 0.

+

+  @param  Buffer           Pointer to the data buffer to be written.

+  @param  NumberOfBytes    Number of bytes to written to the serial device.

+

+  @retval 0                NumberOfBytes is 0.

+  @retval >0               The number of bytes written to the serial device.  

+                           If this value is less than NumberOfBytes, then the read operation failed.

+

+**/

+UINTN

+EFIAPI

+SerialPortWrite (

+  IN UINT8     *Buffer,

+  IN UINTN     NumberOfBytes

+)

+{

+  UINTN  Result;

+  UINT8  Data;

+

+  if (Buffer == NULL) {

+    return 0;

+  }

+

+  Result = NumberOfBytes;

+

+  while ((NumberOfBytes--) != 0) {

+    //

+    // Wait for the serail port to be ready.

+    //

+    do {

+      Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET);

+    } while ((Data & LSR_TXRDY) == 0);

+    IoWrite8 ((UINT16) gUartBase, *Buffer++);

+  }

+

+  return Result;

+}

+

+

+/**

+  Reads data from a serial device into a buffer.

+

+  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.

+  @param  NumberOfBytes    Number of bytes to read from the serial device.

+

+  @retval 0                NumberOfBytes is 0.

+  @retval >0               The number of bytes read from the serial device.  

+                           If this value is less than NumberOfBytes, then the read operation failed.

+

+**/

+UINTN

+EFIAPI

+SerialPortRead (

+  OUT UINT8     *Buffer,

+  IN  UINTN     NumberOfBytes

+)

+{

+  UINTN  Result;

+  UINT8  Data;

+

+  if (NULL == Buffer) {

+    return 0;

+  }

+

+  Result = NumberOfBytes;

+

+  while ((NumberOfBytes--) != 0) {

+    //

+    // Wait for the serail port to be ready.

+    //

+    do {

+      Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET);

+    } while ((Data & LSR_RXDA) == 0);

+

+    *Buffer++ = IoRead8 ((UINT16) gUartBase);

+  }

+

+  return Result;

+}

+

+/**

+  Polls a serial device to see if there is any data waiting to be read.

+

+  Polls aserial device to see if there is any data waiting to be read.

+  If there is data waiting to be read from the serial device, then TRUE is returned.

+  If there is no data waiting to be read from the serial device, then FALSE is returned.

+

+  @retval TRUE             Data is waiting to be read from the serial device.

+  @retval FALSE            There is no data waiting to be read from the serial device.

+

+**/

+BOOLEAN

+EFIAPI

+SerialPortPoll (

+  VOID

+  )

+{

+  UINT8  Data;

+

+  //

+  // Read the serial port status.

+  //

+  Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET);

+

+  return (BOOLEAN) ((Data & LSR_RXDA) != 0);

+}

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/License.txt b/uefi/linaro-edk2/PcAtChipsetPkg/License.txt
new file mode 100644
index 0000000..be68999
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/License.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2012, Intel Corporation. All rights reserved.

+

+Redistribution and use in source and binary forms, with or without

+modification, are permitted provided that the following conditions

+are met:

+

+* Redistributions of source code must retain the above copyright

+  notice, this list of conditions and the following disclaimer.

+* Redistributions in binary form must reproduce the above copyright

+  notice, this list of conditions and the following disclaimer in

+  the documentation and/or other materials provided with the

+  distribution.

+

+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,

+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER

+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN

+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

+POSSIBILITY OF SUCH DAMAGE.

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dec b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dec
new file mode 100644
index 0000000..11c31e1
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dec
@@ -0,0 +1,167 @@
+## @file

+# Public definitions for PcAtChipset package.

+#

+# This package is designed to public interfaces and implementation which follows

+# PcAt defacto standard.

+#

+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>

+#

+# 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.

+#

+##

+

+[Defines]

+  DEC_SPECIFICATION              = 0x00010005

+  PACKAGE_NAME                   = PcAtChipsetPkg

+  PACKAGE_UNI_FILE               = PcAtChipsetPkg.uni

+  PACKAGE_GUID                   = B728689A-52D3-4b8c-AE89-2CE5514CC6DC

+  PACKAGE_VERSION                = 0.3

+

+[Includes]

+  Include

+

+[LibraryClasses]

+  ##  @libraryclass  Provides functions to manage I/O APIC Redirection Table Entries.

+  #

+  IoApicLib|Include/Library/IoApicLib.h

+  

+[Guids]

+  gPcAtChipsetPkgTokenSpaceGuid = { 0x326ae723, 0xae32, 0x4589, { 0x98, 0xb8, 0xca, 0xc2, 0x3c, 0xdc, 0xc1, 0xb1 } }

+

+[PcdsFeatureFlag]

+  ## Indicates the HPET Timer will be configured to use MSI interrupts if the HPET timer supports them, or use I/O APIC interrupts.<BR><BR>

+  #   TRUE  - Configures the HPET Timer to use MSI interrupts if the HPET Timer supports them.<BR>

+  #   FALSE - Configures the HPET Timer to use I/O APIC interrupts.<BR>

+  # @Prompt Configure HPET to use MSI.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetMsiEnable|TRUE|BOOLEAN|0x00001000

+

+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]

+  ## Pcd8259LegacyModeMask defines the default mask value for platform. This value is determined<BR><BR>

+  #  1) If platform only support pure UEFI, value should be set to 0xFFFF or 0xFFFE;

+  #     Because only clock interrupt is allowed in legacy mode in pure UEFI platform.<BR>

+  #  2) If platform install CSM and use thunk module:<BR>

+  #     a) If thunk call provided by CSM binary requires some legacy interrupt support, the corresponding bit 

+  #        should be opened as 0.<BR>

+  #        For example, if keyboard interfaces provided CSM binary use legacy keyboard interrupt in 8259 bit 1, then

+  #        the value should be set to 0xFFFC.<BR>

+  #     b) If all thunk call provied by CSM binary do not require legacy interrupt support, value should be set

+  #        to 0xFFFF or 0xFFFE.<BR>

+  #

+  #  The default value of legacy mode mask could be changed by EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely

+  #  need change it except some special cases such as when initializing the CSM binary, it should be set to 0xFFFF to 

+  #  mask all legacy interrupt. Please restore the original legacy mask value if changing is made for these special case.<BR>

+  # @Prompt 8259 Legacy Mode mask.

+  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x00000001

+  

+  ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy mode's interrrupt controller.

+  #  For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.

+  # @Prompt 8259 Legacy Mode edge level.

+  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0x00000002

+

+  ## Indicates if we need enable IsaAcpiCom1 device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiCom1 device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiCom1 device.<BR>

+  # @Prompt Enable IsaAcpiCom1 device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0x00000003

+

+  ## Indicates if we need enable IsaAcpiCom2 device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiCom2 device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiCom2 device.<BR>

+  # @Prompt Enable IsaAcpiCom12 device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0x00000004

+

+  ## Indicates if we need enable IsaAcpiPs2Keyboard device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiPs2Keyboard device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiPs2Keyboard device.<BR>

+  # @Prompt Enable IsaAcpiPs2Keyboard device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOLEAN|0x00000005

+

+  ## Indicates if we need enable IsaAcpiPs2Mouse device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiPs2Mouse device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiPs2Mouse device.<BR>

+  # @Prompt Enable IsaAcpiPs2Mouse device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEAN|0x00000006

+

+  ## Indicates if we need enable IsaAcpiFloppyA device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiFloppyA device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiFloppyA device.<BR>

+  # @Prompt Enable IsaAcpiFloppyA device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN|0x00000007

+

+  ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>

+  #   TRUE  - Enables IsaAcpiFloppyB device.<BR>

+  #   FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>

+  # @Prompt Enable IsaAcpiFloppyB device.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x00000008

+

+  ## This PCD specifies the base address of the HPET timer.

+  # @Prompt HPET base address.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress|0xFED00000|UINT32|0x00000009

+

+  ## This PCD specifies the Local APIC Interrupt Vector for the HPET Timer.

+  # @Prompt HPET local APIC vector.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetLocalApicVector|0x40|UINT8|0x0000000A

+

+  ## This PCD specifies the defaut period of the HPET Timer in 100 ns units.

+  #  The default value of 100000 100 ns units is the same as 10 ms.

+  # @Prompt Default period of HPET timer.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdHpetDefaultTimerPeriod|100000|UINT64|0x0000000B

+  

+  ## This PCD specifies the base address of the IO APIC.

+  # @Prompt IO APIC base address.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress|0xFEC00000|UINT32|0x0000000C

+

+  ## This PCD specifies the minimal valid year in RTC.

+  # @Prompt Minimal valid year in RTC.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear|1998|UINT16|0x0000000D

+

+  ## This PCD specifies the maximal valid year in RTC.

+  # @Prompt Maximal valid year in RTC.

+  gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2099|UINT16|0x0000000E

+  

+[PcdsFixedAtBuild, PcdsPatchableInModule]

+  ## Defines the ACPI register set base address.

+  #  The invalid 0xFFFF is as its default value. It must be configured to the real value. 

+  # @Prompt ACPI Timer IO Port Address

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress         |0xFFFF|UINT16|0x00000010

+

+  ## Defines the PCI Bus Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.

+  # @Prompt ACPI Hardware PCI Bus Number

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber            |  0x00| UINT8|0x00000011

+

+  ## Defines the PCI Device Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.

+  #  The invalid 0xFF is as its default value. It must be configured to the real value. 

+  # @Prompt ACPI Hardware PCI Device Number

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber         |  0xFF| UINT8|0x00000012

+

+  ## Defines the PCI Function Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.

+  #  The invalid 0xFF is as its default value. It must be configured to the real value. 

+  # @Prompt ACPI Hardware PCI Function Number

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber       |  0xFF| UINT8|0x00000013

+  

+  ## Defines the PCI Register Offset of the PCI device that contains the Enable for ACPI hardware registers.

+  #  The invalid 0xFFFF is as its default value. It must be configured to the real value. 

+  # @Prompt ACPI Hardware PCI Register Offset

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset |0xFFFF|UINT16|0x00000014

+  

+  ## Defines the bit mask that must be set to enable the APIC hardware register BAR.

+  # @Prompt ACPI Hardware PCI Bar Enable BitMask

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask           |  0x00| UINT8|0x00000015

+  

+  ## Defines the PCI Register Offset of the PCI device that contains the BAR for ACPI hardware registers.

+  #  The invalid 0xFFFF is as its default value. It must be configured to the real value. 

+  # @Prompt ACPI Hardware PCI Bar Register Offset

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset    |0xFFFF|UINT16|0x00000016

+

+  ## Defines the offset to the 32-bit Timer Value register that resides within the ACPI BAR.

+  # @Prompt Offset to 32-bit Timer register in ACPI BAR

+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset              |0x0008|UINT16|0x00000017

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  PcAtChipsetPkgExtra.uni
\ No newline at end of file
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dsc b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dsc
new file mode 100644
index 0000000..152f5f6
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.dsc
@@ -0,0 +1,62 @@
+## @file

+#  PC/AT Chipset Package

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  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.

+#

+##

+

+[Defines]

+  PLATFORM_NAME                  = PcAtChipset

+  PLATFORM_GUID                  = a653167b-34d7-4b91-bfe3-f0c7608f48da

+  PLATFORM_VERSION               = 0.3

+  DSC_SPECIFICATION              = 0x00010005

+  OUTPUT_DIRECTORY               = Build/PcAtChipset

+  SUPPORTED_ARCHITECTURES        = IA32|X64

+  BUILD_TARGETS                  = DEBUG|RELEASE

+  SKUID_IDENTIFIER               = DEFAULT

+

+[LibraryClasses]

+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf

+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf

+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf

+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf  

+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf

+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf

+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf

+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf

+  TimerLib|PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf

+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf

+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf

+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf

+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf

+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf

+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf

+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf

+  ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf

+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf

+  LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf

+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf

+

+[Components]

+  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf

+  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf

+  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf

+  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf

+  PcAtChipsetPkg/KbcResetDxe/Reset.inf

+  PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf

+  PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf

+  PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf

+  PcAtChipsetPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf

+  PcAtChipsetPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf

+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf

+  PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.uni
new file mode 100644
index 0000000..080f302
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkg.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkgExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkgExtra.uni
new file mode 100644
index 0000000..e56154f
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcAtChipsetPkgExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
new file mode 100644
index 0000000..23f8d3b
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
@@ -0,0 +1,1210 @@
+/** @file

+  RTC Architectural Protocol GUID as defined in DxeCis 0.96.

+

+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+#include "PcRtc.h"

+

+/**

+  Compare the Hour, Minute and Second of the From time and the To time.

+  

+  Only compare H/M/S in EFI_TIME and ignore other fields here.

+

+  @param From   the first time

+  @param To     the second time

+

+  @return  >0   The H/M/S of the From time is later than those of To time

+  @return  ==0  The H/M/S of the From time is same as those of To time

+  @return  <0   The H/M/S of the From time is earlier than those of To time

+**/

+INTN

+CompareHMS (

+  IN EFI_TIME   *From,

+  IN EFI_TIME   *To

+  );

+

+/**

+  To check if second date is later than first date within 24 hours.

+

+  @param  From   the first date

+  @param  To     the second date

+

+  @retval TRUE   From is previous to To within 24 hours.

+  @retval FALSE  From is later, or it is previous to To more than 24 hours.

+**/

+BOOLEAN

+IsWithinOneDay (

+  IN EFI_TIME   *From,

+  IN EFI_TIME   *To

+  );

+

+/**

+  Read RTC content through its registers.

+

+  @param  Address  Address offset of RTC. It is recommended to use macros such as

+                   RTC_ADDRESS_SECONDS.

+

+  @return The data of UINT8 type read from RTC.

+**/

+UINT8

+RtcRead (

+  IN  UINT8 Address

+  )

+{

+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));

+  return IoRead8 (PCAT_RTC_DATA_REGISTER);

+}

+

+/**

+  Write RTC through its registers.

+

+  @param  Address  Address offset of RTC. It is recommended to use macros such as

+                   RTC_ADDRESS_SECONDS.

+  @param  Data     The content you want to write into RTC.

+

+**/

+VOID

+RtcWrite (

+  IN  UINT8   Address,

+  IN  UINT8   Data

+  )

+{

+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));

+  IoWrite8 (PCAT_RTC_DATA_REGISTER, Data);

+}

+

+/**

+  Initialize RTC.

+

+  @param  Global            For global use inside this module.

+

+  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.

+  @retval EFI_SUCCESS       Initialization successful.

+

+**/

+EFI_STATUS

+PcRtcInit (

+  IN PC_RTC_MODULE_GLOBALS  *Global

+  )

+{

+  EFI_STATUS      Status;

+  RTC_REGISTER_A  RegisterA;

+  RTC_REGISTER_B  RegisterB;

+  RTC_REGISTER_D  RegisterD;

+  UINT8           Century;

+  EFI_TIME        Time;

+  UINTN           DataSize;

+  UINT32          TimerVar;

+  BOOLEAN         Enabled;

+  BOOLEAN         Pending;

+

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Initialize RTC Register

+  //

+  // Make sure Division Chain is properly configured,

+  // or RTC clock won't "tick" -- time won't increment

+  //

+  RegisterA.Data = RTC_INIT_REGISTER_A;

+  RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);

+

+  //

+  // Read Register B

+  //

+  RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);

+

+  //

+  // Clear RTC flag register

+  //

+  RtcRead (RTC_ADDRESS_REGISTER_C);

+

+  //

+  // Clear RTC register D

+  //

+  RegisterD.Data = RTC_INIT_REGISTER_D;

+  RtcWrite (RTC_ADDRESS_REGISTER_D, RegisterD.Data);

+

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+    //

+    // Set the variable with default value if the RTC is functioning incorrectly.

+    //

+    Global->SavedTimeZone = EFI_UNSPECIFIED_TIMEZONE;

+    Global->Daylight      = 0;

+    if (!EfiAtRuntime ()) {

+      EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Get the Time/Date/Daylight Savings values.

+  //

+  Time.Second = RtcRead (RTC_ADDRESS_SECONDS);

+  Time.Minute = RtcRead (RTC_ADDRESS_MINUTES);

+  Time.Hour   = RtcRead (RTC_ADDRESS_HOURS);

+  Time.Day    = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);

+  Time.Month  = RtcRead (RTC_ADDRESS_MONTH);

+  Time.Year   = RtcRead (RTC_ADDRESS_YEAR);

+

+  Century = RtcRead (RTC_ADDRESS_CENTURY);

+  

+  //

+  // Set RTC configuration after get original time

+  // The value of bit AIE should be reserved.

+  //

+  RtcWrite (RTC_ADDRESS_REGISTER_B, (UINT8)(RTC_INIT_REGISTER_B | (RegisterB.Data & BIT5)));

+

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+ 

+  //

+  // Get the data of Daylight saving and time zone, if they have been

+  // stored in NV variable during previous boot.

+  //

+  DataSize = sizeof (UINT32);

+  Status = EfiGetVariable (

+             L"RTC",

+             &gEfiCallerIdGuid,

+             NULL,

+             &DataSize,

+             (VOID *) &TimerVar

+             );

+  if (!EFI_ERROR (Status)) {

+    Time.TimeZone = (INT16) TimerVar;

+    Time.Daylight = (UINT8) (TimerVar >> 16);

+  } else {

+    Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;

+    Time.Daylight = 0;  

+  }

+

+  //

+  // Validate time fields

+  //

+  Status = ConvertRtcTimeToEfiTime (&Time, Century, RegisterB);

+  if (!EFI_ERROR (Status)) {

+    Status = RtcTimeFieldsValid (&Time);

+  }

+  if (EFI_ERROR (Status)) {

+    //

+    // Report Status Code to indicate that the RTC has bad date and time

+    //

+    REPORT_STATUS_CODE (

+      EFI_ERROR_CODE | EFI_ERROR_MINOR,

+      (EFI_SOFTWARE_DXE_RT_DRIVER | EFI_SW_EC_BAD_DATE_TIME)

+      );

+    Time.Second = RTC_INIT_SECOND;

+    Time.Minute = RTC_INIT_MINUTE;

+    Time.Hour   = RTC_INIT_HOUR;

+    Time.Day    = RTC_INIT_DAY;

+    Time.Month  = RTC_INIT_MONTH;

+    Time.Year   = RTC_INIT_YEAR;

+    Time.Nanosecond  = 0;

+    Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;

+    Time.Daylight = 0;

+  }

+

+  //

+  // Reset time value according to new RTC configuration

+  //

+  Status = PcRtcSetTime (&Time, Global);

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Reset wakeup time value to valid state when wakeup alarm is disabled and wakeup time is invalid.

+  // Global variable has already had valid SavedTimeZone and Daylight,

+  // so we can use them to get and set wakeup time.

+  //

+  Status = PcRtcGetWakeupTime (&Enabled, &Pending, &Time, Global);

+  if ((Enabled) || (!EFI_ERROR (Status))) {

+    return EFI_SUCCESS;

+  }

+  

+  //

+  // When wakeup time is disabled and invalid, reset wakeup time register to valid state 

+  // but keep wakeup alarm disabled.

+  //

+  Time.Second = RTC_INIT_SECOND;

+  Time.Minute = RTC_INIT_MINUTE;

+  Time.Hour   = RTC_INIT_HOUR;

+  Time.Day    = RTC_INIT_DAY;

+  Time.Month  = RTC_INIT_MONTH;

+  Time.Year   = RTC_INIT_YEAR;

+  Time.Nanosecond  = 0;

+  Time.TimeZone = Global->SavedTimeZone;

+  Time.Daylight = Global->Daylight;;

+

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  

+  ConvertEfiTimeToRtcTime (&Time, RegisterB, &Century);

+

+  //

+  // Set the Y/M/D info to variable as it has no corresponding hw registers.

+  //

+  Status =  EfiSetVariable (

+              L"RTCALARM",

+              &gEfiCallerIdGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+              sizeof (Time),

+              &Time

+              );

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+      EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Inhibit updates of the RTC

+  //

+  RegisterB.Bits.Set  = 1;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+ 

+  //

+  // Set RTC alarm time registers

+  //

+  RtcWrite (RTC_ADDRESS_SECONDS_ALARM, Time.Second);

+  RtcWrite (RTC_ADDRESS_MINUTES_ALARM, Time.Minute);

+  RtcWrite (RTC_ADDRESS_HOURS_ALARM, Time.Hour);

+

+  //

+  // Allow updates of the RTC registers

+  //

+  RegisterB.Bits.Set = 0;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+ 

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+  Returns the current time and date information, and the time-keeping capabilities

+  of the hardware platform.

+

+  @param  Time          A pointer to storage to receive a snapshot of the current time.

+  @param  Capabilities  An optional pointer to a buffer to receive the real time clock

+                        device's capabilities.

+  @param  Global        For global use inside this module.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER  Time is NULL.

+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.

+

+**/

+EFI_STATUS

+PcRtcGetTime (

+  OUT  EFI_TIME               *Time,

+  OUT  EFI_TIME_CAPABILITIES  *Capabilities,  OPTIONAL

+  IN   PC_RTC_MODULE_GLOBALS  *Global

+  )

+{

+  EFI_STATUS      Status;

+  RTC_REGISTER_B  RegisterB;

+  UINT8           Century;

+

+  //

+  // Check parameters for null pointer

+  //

+  if (Time == NULL) {

+    return EFI_INVALID_PARAMETER;

+

+  }

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+      if (!EfiAtRuntime ()) {

+        EfiReleaseLock (&Global->RtcLock);

+      }

+    return Status;

+  }

+  //

+  // Read Register B

+  //

+  RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);

+

+  //

+  // Get the Time/Date/Daylight Savings values.

+  //

+  Time->Second  = RtcRead (RTC_ADDRESS_SECONDS);

+  Time->Minute  = RtcRead (RTC_ADDRESS_MINUTES);

+  Time->Hour    = RtcRead (RTC_ADDRESS_HOURS);

+  Time->Day     = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);

+  Time->Month   = RtcRead (RTC_ADDRESS_MONTH);

+  Time->Year    = RtcRead (RTC_ADDRESS_YEAR);

+

+  Century = RtcRead (RTC_ADDRESS_CENTURY);

+  

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+

+  //

+  // Get the variable that contains the TimeZone and Daylight fields

+  //

+  Time->TimeZone  = Global->SavedTimeZone;

+  Time->Daylight  = Global->Daylight;

+

+  //

+  // Make sure all field values are in correct range

+  //

+  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);

+  if (!EFI_ERROR (Status)) {

+    Status = RtcTimeFieldsValid (Time);

+  }

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  //  Fill in Capabilities if it was passed in

+  //

+  if (Capabilities != NULL) {

+    Capabilities->Resolution = 1;

+    //

+    // 1 hertz

+    //

+    Capabilities->Accuracy = 50000000;

+    //

+    // 50 ppm

+    //

+    Capabilities->SetsToZero = FALSE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets the current local time and date information.

+

+  @param  Time                  A pointer to the current time.

+  @param  Global                For global use inside this module.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.

+

+**/

+EFI_STATUS

+PcRtcSetTime (

+  IN EFI_TIME                *Time,

+  IN PC_RTC_MODULE_GLOBALS   *Global

+  )

+{

+  EFI_STATUS      Status;

+  EFI_TIME        RtcTime;

+  RTC_REGISTER_B  RegisterB;

+  UINT8           Century;

+  UINT32          TimerVar;

+

+  if (Time == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  //

+  // Make sure that the time fields are valid

+  //

+  Status = RtcTimeFieldsValid (Time);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  CopyMem (&RtcTime, Time, sizeof (EFI_TIME));

+

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+     if (!EfiAtRuntime ()) {

+       EfiReleaseLock (&Global->RtcLock);

+     }

+    return Status;

+  }

+  

+  //

+  // Write timezone and daylight to RTC variable

+  //

+  TimerVar = Time->Daylight;

+  TimerVar = (UINT32) ((TimerVar << 16) | (UINT16)(Time->TimeZone));

+  Status =  EfiSetVariable (

+              L"RTC",

+              &gEfiCallerIdGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+              sizeof (TimerVar),

+              &TimerVar

+              );

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+      EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+

+  //

+  // Read Register B, and inhibit updates of the RTC

+  //

+  RegisterB.Data      = RtcRead (RTC_ADDRESS_REGISTER_B);

+  RegisterB.Bits.Set  = 1;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+

+  ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);

+

+  RtcWrite (RTC_ADDRESS_SECONDS, RtcTime.Second);

+  RtcWrite (RTC_ADDRESS_MINUTES, RtcTime.Minute);

+  RtcWrite (RTC_ADDRESS_HOURS, RtcTime.Hour);

+  RtcWrite (RTC_ADDRESS_DAY_OF_THE_MONTH, RtcTime.Day);

+  RtcWrite (RTC_ADDRESS_MONTH, RtcTime.Month);

+  RtcWrite (RTC_ADDRESS_YEAR, (UINT8) RtcTime.Year);

+  RtcWrite (RTC_ADDRESS_CENTURY, Century);

+

+  //

+  // Allow updates of the RTC registers

+  //

+  RegisterB.Bits.Set = 0;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+  //

+  // Set the variable that contains the TimeZone and Daylight fields

+  //

+  Global->SavedTimeZone = Time->TimeZone;

+  Global->Daylight      = Time->Daylight;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Returns the current wakeup alarm clock setting.

+

+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.

+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgment.

+  @param  Time     The current alarm setting.

+  @param  Global   For global use inside this module.

+

+  @retval EFI_SUCCESS           The alarm settings were returned.

+  @retval EFI_INVALID_PARAMETER Enabled is NULL.

+  @retval EFI_INVALID_PARAMETER Pending is NULL.

+  @retval EFI_INVALID_PARAMETER Time is NULL.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+PcRtcGetWakeupTime (

+  OUT BOOLEAN                *Enabled,

+  OUT BOOLEAN                *Pending,

+  OUT EFI_TIME               *Time,

+  IN  PC_RTC_MODULE_GLOBALS  *Global

+  )

+{

+  EFI_STATUS      Status;

+  RTC_REGISTER_B  RegisterB;

+  RTC_REGISTER_C  RegisterC;

+  UINT8           Century;

+  EFI_TIME        RtcTime;

+  UINTN           DataSize;

+

+  //

+  // Check parameters for null pointers

+  //

+  if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {

+    return EFI_INVALID_PARAMETER;

+

+  }

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Read Register B and Register C

+  //

+  RegisterB.Data  = RtcRead (RTC_ADDRESS_REGISTER_B);

+  RegisterC.Data  = RtcRead (RTC_ADDRESS_REGISTER_C);

+

+  //

+  // Get the Time/Date/Daylight Savings values.

+  //

+  *Enabled = RegisterB.Bits.Aie;

+  *Pending = RegisterC.Bits.Af;

+

+  Time->Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);

+  Time->Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);

+  Time->Hour   = RtcRead (RTC_ADDRESS_HOURS_ALARM);

+  Time->Day    = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);

+  Time->Month  = RtcRead (RTC_ADDRESS_MONTH);

+  Time->Year   = RtcRead (RTC_ADDRESS_YEAR);

+  Time->TimeZone = Global->SavedTimeZone;

+  Time->Daylight = Global->Daylight;

+

+  Century = RtcRead (RTC_ADDRESS_CENTURY);

+

+  //

+  // Get the alarm info from variable

+  //

+  DataSize = sizeof (EFI_TIME);

+  Status = EfiGetVariable (

+              L"RTCALARM",

+              &gEfiCallerIdGuid,

+              NULL,

+              &DataSize,

+              &RtcTime

+              );

+  if (!EFI_ERROR (Status)) {

+    //

+    // The alarm variable exists. In this case, we read variable to get info.

+    //

+    Time->Day   = RtcTime.Day;

+    Time->Month = RtcTime.Month;

+    Time->Year  = RtcTime.Year;

+  }

+

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+

+  //

+  // Make sure all field values are in correct range

+  //

+  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);

+  if (!EFI_ERROR (Status)) {

+    Status = RtcTimeFieldsValid (Time);

+  }

+  if (EFI_ERROR (Status)) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets the system wakeup alarm clock time.

+

+  @param  Enabled  Enable or disable the wakeup alarm.

+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.

+                   If Enable is FALSE, then this parameter is optional, and may be NULL.

+  @param  Global   For global use inside this module.

+

+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.

+                                If Enable is FALSE, then the wakeup alarm was disabled.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+PcRtcSetWakeupTime (

+  IN BOOLEAN                Enable,

+  IN EFI_TIME               *Time,   OPTIONAL

+  IN PC_RTC_MODULE_GLOBALS  *Global

+  )

+{

+  EFI_STATUS            Status;

+  EFI_TIME              RtcTime;

+  RTC_REGISTER_B        RegisterB;

+  UINT8                 Century;

+  EFI_TIME_CAPABILITIES Capabilities;

+

+  ZeroMem (&RtcTime, sizeof (RtcTime));

+

+  if (Enable) {

+

+    if (Time == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Make sure that the time fields are valid

+    //

+    Status = RtcTimeFieldsValid (Time);

+    if (EFI_ERROR (Status)) {

+      return EFI_INVALID_PARAMETER;

+    }

+    //

+    // Just support set alarm time within 24 hours

+    //

+    PcRtcGetTime (&RtcTime, &Capabilities, Global);

+    Status = RtcTimeFieldsValid (&RtcTime);

+    if (EFI_ERROR (Status)) {

+      return EFI_DEVICE_ERROR;

+    }

+    if (!IsWithinOneDay (&RtcTime, Time)) {

+      return EFI_UNSUPPORTED;

+    }

+    //

+    // Make a local copy of the time and date

+    //

+    CopyMem (&RtcTime, Time, sizeof (EFI_TIME));

+

+  }

+  //

+  // Acquire RTC Lock to make access to RTC atomic

+  //

+  if (!EfiAtRuntime ()) {

+    EfiAcquireLock (&Global->RtcLock);

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be updated

+  //

+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Read Register B

+  //

+  RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);

+

+  if (Enable) {

+    ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);

+  } else {

+    //

+    // if the alarm is disable, record the current setting.

+    //

+    RtcTime.Second  = RtcRead (RTC_ADDRESS_SECONDS_ALARM);

+    RtcTime.Minute  = RtcRead (RTC_ADDRESS_MINUTES_ALARM);

+    RtcTime.Hour    = RtcRead (RTC_ADDRESS_HOURS_ALARM);

+    RtcTime.Day     = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);

+    RtcTime.Month   = RtcRead (RTC_ADDRESS_MONTH);

+    RtcTime.Year    = RtcRead (RTC_ADDRESS_YEAR);

+    RtcTime.TimeZone = Global->SavedTimeZone;

+    RtcTime.Daylight = Global->Daylight;

+  }

+

+  //

+  // Set the Y/M/D info to variable as it has no corresponding hw registers.

+  //

+  Status =  EfiSetVariable (

+              L"RTCALARM",

+              &gEfiCallerIdGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,

+              sizeof (RtcTime),

+              &RtcTime

+              );

+  if (EFI_ERROR (Status)) {

+    if (!EfiAtRuntime ()) {

+      EfiReleaseLock (&Global->RtcLock);

+    }

+    return EFI_DEVICE_ERROR;

+  }

+  

+  //

+  // Inhibit updates of the RTC

+  //

+  RegisterB.Bits.Set  = 1;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+

+  if (Enable) {

+    //

+    // Set RTC alarm time

+    //

+    RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);

+    RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);

+    RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);

+

+    RegisterB.Bits.Aie = 1;

+

+  } else {

+    RegisterB.Bits.Aie = 0;

+  }

+  //

+  // Allow updates of the RTC registers

+  //

+  RegisterB.Bits.Set = 0;

+  RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);

+

+  //

+  // Release RTC Lock.

+  //

+  if (!EfiAtRuntime ()) {

+    EfiReleaseLock (&Global->RtcLock);

+  }

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Checks an 8-bit BCD value, and converts to an 8-bit value if valid.

+

+  This function checks the 8-bit BCD value specified by Value.

+  If valid, the function converts it to an 8-bit value and returns it.

+  Otherwise, return 0xff.

+

+  @param   Value The 8-bit BCD value to check and convert

+

+  @return  The 8-bit value converted. Or 0xff if Value is invalid.

+

+**/

+UINT8

+CheckAndConvertBcd8ToDecimal8 (

+  IN  UINT8  Value

+  )

+{

+  if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {

+    return BcdToDecimal8 (Value);

+  }

+

+  return 0xff;

+}

+

+/**

+  Converts time read from RTC to EFI_TIME format defined by UEFI spec.

+

+  This function converts raw time data read from RTC to the EFI_TIME format

+  defined by UEFI spec.

+  If data mode of RTC is BCD, then converts it to decimal,

+  If RTC is in 12-hour format, then converts it to 24-hour format.

+

+  @param   Time       On input, the time data read from RTC to convert

+                      On output, the time converted to UEFI format

+  @param   Century    Value of century read from RTC.

+  @param   RegisterB  Value of Register B of RTC, indicating data mode

+                      and hour format.

+

+  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.

+  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.

+

+**/

+EFI_STATUS

+ConvertRtcTimeToEfiTime (

+  IN OUT EFI_TIME        *Time,

+  IN     UINT8           Century,

+  IN     RTC_REGISTER_B  RegisterB

+  )

+{

+  BOOLEAN IsPM;

+

+  if ((Time->Hour & 0x80) != 0) {

+    IsPM = TRUE;

+  } else {

+    IsPM = FALSE;

+  }

+

+  Time->Hour = (UINT8) (Time->Hour & 0x7f);

+

+  if (RegisterB.Bits.Dm == 0) {

+    Time->Year    = CheckAndConvertBcd8ToDecimal8 ((UINT8) Time->Year);

+    Time->Month   = CheckAndConvertBcd8ToDecimal8 (Time->Month);

+    Time->Day     = CheckAndConvertBcd8ToDecimal8 (Time->Day);

+    Time->Hour    = CheckAndConvertBcd8ToDecimal8 (Time->Hour);

+    Time->Minute  = CheckAndConvertBcd8ToDecimal8 (Time->Minute);

+    Time->Second  = CheckAndConvertBcd8ToDecimal8 (Time->Second);

+  }

+  Century       = CheckAndConvertBcd8ToDecimal8 (Century);

+

+  if (Time->Year == 0xff || Time->Month == 0xff || Time->Day == 0xff ||

+      Time->Hour == 0xff || Time->Minute == 0xff || Time->Second == 0xff ||

+      Century == 0xff) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Time->Year = (UINT16) (Century * 100 + Time->Year);

+

+  //

+  // If time is in 12 hour format, convert it to 24 hour format

+  //

+  if (RegisterB.Bits.Mil == 0) {

+    if (IsPM && Time->Hour < 12) {

+      Time->Hour = (UINT8) (Time->Hour + 12);

+    }

+

+    if (!IsPM && Time->Hour == 12) {

+      Time->Hour = 0;

+    }

+  }

+

+  Time->Nanosecond  = 0;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Wait for a period for the RTC to be ready.

+

+  @param    Timeout  Tell how long it should take to wait.

+

+  @retval   EFI_DEVICE_ERROR   RTC device error.

+  @retval   EFI_SUCCESS        RTC is updated and ready.  

+**/

+EFI_STATUS

+RtcWaitToUpdate (

+  UINTN Timeout

+  )

+{

+  RTC_REGISTER_A  RegisterA;

+  RTC_REGISTER_D  RegisterD;

+

+  //

+  // See if the RTC is functioning correctly

+  //

+  RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);

+

+  if (RegisterD.Bits.Vrt == 0) {

+    return EFI_DEVICE_ERROR;

+  }

+  //

+  // Wait for up to 0.1 seconds for the RTC to be ready.

+  //

+  Timeout         = (Timeout / 10) + 1;

+  RegisterA.Data  = RtcRead (RTC_ADDRESS_REGISTER_A);

+  while (RegisterA.Bits.Uip == 1 && Timeout > 0) {

+    MicroSecondDelay (10);

+    RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);

+    Timeout--;

+  }

+

+  RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);

+  if (Timeout == 0 || RegisterD.Bits.Vrt == 0) {

+    return EFI_DEVICE_ERROR;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  See if all fields of a variable of EFI_TIME type is correct.

+

+  @param   Time   The time to be checked.

+

+  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.

+  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.

+

+**/

+EFI_STATUS

+RtcTimeFieldsValid (

+  IN EFI_TIME *Time

+  )

+{

+  if (Time->Year < PcdGet16 (PcdMinimalValidYear) ||

+      Time->Year > PcdGet16 (PcdMaximalValidYear) ||

+      Time->Month < 1 ||

+      Time->Month > 12 ||

+      (!DayValid (Time)) ||

+      Time->Hour > 23 ||

+      Time->Minute > 59 ||

+      Time->Second > 59 ||

+      Time->Nanosecond > 999999999 ||

+      (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||

+      ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  See if field Day of an EFI_TIME is correct.

+

+  @param    Time   Its Day field is to be checked.

+

+  @retval   TRUE   Day field of Time is correct.

+  @retval   FALSE  Day field of Time is NOT correct.

+**/

+BOOLEAN

+DayValid (

+  IN  EFI_TIME  *Time

+  )

+{

+  INTN  DayOfMonth[12];

+

+  DayOfMonth[0] = 31;

+  DayOfMonth[1] = 29;

+  DayOfMonth[2] = 31;

+  DayOfMonth[3] = 30;

+  DayOfMonth[4] = 31;

+  DayOfMonth[5] = 30;

+  DayOfMonth[6] = 31;

+  DayOfMonth[7] = 31;

+  DayOfMonth[8] = 30;

+  DayOfMonth[9] = 31;

+  DayOfMonth[10] = 30;

+  DayOfMonth[11] = 31;

+

+  //

+  // The validity of Time->Month field should be checked before

+  //

+  ASSERT (Time->Month >=1);

+  ASSERT (Time->Month <=12);

+  if (Time->Day < 1 ||

+      Time->Day > DayOfMonth[Time->Month - 1] ||

+      (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))

+      ) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Check if it is a leap year.

+

+  @param    Time   The time to be checked.

+

+  @retval   TRUE   It is a leap year.

+  @retval   FALSE  It is NOT a leap year.

+**/

+BOOLEAN

+IsLeapYear (

+  IN EFI_TIME   *Time

+  )

+{

+  if (Time->Year % 4 == 0) {

+    if (Time->Year % 100 == 0) {

+      if (Time->Year % 400 == 0) {

+        return TRUE;

+      } else {

+        return FALSE;

+      }

+    } else {

+      return TRUE;

+    }

+  } else {

+    return FALSE;

+  }

+}

+

+/**

+  Converts time from EFI_TIME format defined by UEFI spec to RTC's.

+

+  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.

+  If data mode of RTC is BCD, then converts EFI_TIME to it.

+  If RTC is in 12-hour format, then converts EFI_TIME to it.

+

+  @param   Time       On input, the time data read from UEFI to convert

+                      On output, the time converted to RTC format

+  @param   RegisterB  Value of Register B of RTC, indicating data mode

+  @param   Century    It is set according to EFI_TIME Time.

+

+**/

+VOID

+ConvertEfiTimeToRtcTime (

+  IN OUT EFI_TIME        *Time,

+  IN     RTC_REGISTER_B  RegisterB,

+     OUT UINT8           *Century

+  )

+{

+  BOOLEAN IsPM;

+

+  IsPM = TRUE;

+  //

+  // Adjust hour field if RTC is in 12 hour mode

+  //

+  if (RegisterB.Bits.Mil == 0) {

+    if (Time->Hour < 12) {

+      IsPM = FALSE;

+    }

+

+    if (Time->Hour >= 13) {

+      Time->Hour = (UINT8) (Time->Hour - 12);

+    } else if (Time->Hour == 0) {

+      Time->Hour = 12;

+    }

+  }

+  //

+  // Set the Time/Date/Daylight Savings values.

+  //

+  *Century    = DecimalToBcd8 ((UINT8) (Time->Year / 100));

+

+  Time->Year  = (UINT16) (Time->Year % 100);

+

+  if (RegisterB.Bits.Dm == 0) {

+    Time->Year    = DecimalToBcd8 ((UINT8) Time->Year);

+    Time->Month   = DecimalToBcd8 (Time->Month);

+    Time->Day     = DecimalToBcd8 (Time->Day);

+    Time->Hour    = DecimalToBcd8 (Time->Hour);

+    Time->Minute  = DecimalToBcd8 (Time->Minute);

+    Time->Second  = DecimalToBcd8 (Time->Second);

+  }

+  //

+  // If we are in 12 hour mode and PM is set, then set bit 7 of the Hour field.

+  //

+  if (RegisterB.Bits.Mil == 0 && IsPM) {

+    Time->Hour = (UINT8) (Time->Hour | 0x80);

+  }

+}

+

+/**

+  Compare the Hour, Minute and Second of the From time and the To time.

+  

+  Only compare H/M/S in EFI_TIME and ignore other fields here.

+

+  @param From   the first time

+  @param To     the second time

+

+  @return  >0   The H/M/S of the From time is later than those of To time

+  @return  ==0  The H/M/S of the From time is same as those of To time

+  @return  <0   The H/M/S of the From time is earlier than those of To time

+**/

+INTN

+CompareHMS (

+  IN EFI_TIME   *From,

+  IN EFI_TIME   *To

+  )

+{

+  if ((From->Hour > To->Hour) ||

+     ((From->Hour == To->Hour) && (From->Minute > To->Minute)) ||

+     ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second > To->Second))) {

+    return 1;

+  } else if ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second == To->Second)) {

+    return 0;

+  } else {

+    return -1;

+  }

+}

+

+/**

+  To check if second date is later than first date within 24 hours.

+

+  @param  From   the first date

+  @param  To     the second date

+

+  @retval TRUE   From is previous to To within 24 hours.

+  @retval FALSE  From is later, or it is previous to To more than 24 hours.

+**/

+BOOLEAN

+IsWithinOneDay (

+  IN EFI_TIME  *From,

+  IN EFI_TIME  *To

+  )

+{

+  UINT8   DayOfMonth[12];

+  BOOLEAN Adjacent;

+

+  DayOfMonth[0] = 31;

+  DayOfMonth[1] = 29;

+  DayOfMonth[2] = 31;

+  DayOfMonth[3] = 30;

+  DayOfMonth[4] = 31;

+  DayOfMonth[5] = 30;

+  DayOfMonth[6] = 31;

+  DayOfMonth[7] = 31;

+  DayOfMonth[8] = 30;

+  DayOfMonth[9] = 31;

+  DayOfMonth[10] = 30;

+  DayOfMonth[11] = 31;

+

+  Adjacent = FALSE;

+

+  //

+  // The validity of From->Month field should be checked before

+  //

+  ASSERT (From->Month >=1);

+  ASSERT (From->Month <=12);

+  

+  if (From->Year == To->Year) {

+    if (From->Month == To->Month) {

+      if ((From->Day + 1) == To->Day) {

+        if ((CompareHMS(From, To) >= 0)) {

+          Adjacent = TRUE;

+        }

+      } else if (From->Day == To->Day) {

+        if ((CompareHMS(From, To) <= 0)) {

+          Adjacent = TRUE;

+        }

+      }

+    } else if (((From->Month + 1) == To->Month) && (To->Day == 1)) {

+      if ((From->Month == 2) && !IsLeapYear(From)) {

+        if (From->Day == 28) {

+          if ((CompareHMS(From, To) >= 0)) {

+            Adjacent = TRUE;

+          }

+        }

+      } else if (From->Day == DayOfMonth[From->Month - 1]) {

+        if ((CompareHMS(From, To) >= 0)) {

+           Adjacent = TRUE;

+        }

+      }

+    }

+  } else if (((From->Year + 1) == To->Year) &&

+             (From->Month == 12) &&

+             (From->Day   == 31) &&

+             (To->Month   == 1)  &&

+             (To->Day     == 1)) {

+    if ((CompareHMS(From, To) >= 0)) {

+      Adjacent = TRUE;

+    }

+  }

+

+  return Adjacent;

+}

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h
new file mode 100644
index 0000000..020d715
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h
@@ -0,0 +1,365 @@
+/** @file

+  Header file for real time clock driver.

+

+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+

+#ifndef _RTC_H_

+#define _RTC_H_

+

+

+#include <Uefi.h>

+

+#include <Protocol/RealTimeClock.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/IoLib.h>

+#include <Library/TimerLib.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/PcdLib.h>

+#include <Library/ReportStatusCodeLib.h>

+

+

+typedef struct {

+  EFI_LOCK  RtcLock;

+  INT16     SavedTimeZone;

+  UINT8     Daylight;

+} PC_RTC_MODULE_GLOBALS;

+

+#define PCAT_RTC_ADDRESS_REGISTER 0x70

+#define PCAT_RTC_DATA_REGISTER    0x71

+

+//

+// Dallas DS12C887 Real Time Clock

+//

+#define RTC_ADDRESS_SECONDS           0   // R/W  Range 0..59

+#define RTC_ADDRESS_SECONDS_ALARM     1   // R/W  Range 0..59

+#define RTC_ADDRESS_MINUTES           2   // R/W  Range 0..59

+#define RTC_ADDRESS_MINUTES_ALARM     3   // R/W  Range 0..59

+#define RTC_ADDRESS_HOURS             4   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM

+#define RTC_ADDRESS_HOURS_ALARM       5   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM

+#define RTC_ADDRESS_DAY_OF_THE_WEEK   6   // R/W  Range 1..7

+#define RTC_ADDRESS_DAY_OF_THE_MONTH  7   // R/W  Range 1..31

+#define RTC_ADDRESS_MONTH             8   // R/W  Range 1..12

+#define RTC_ADDRESS_YEAR              9   // R/W  Range 0..99

+#define RTC_ADDRESS_REGISTER_A        10  // R/W[0..6]  R0[7]

+#define RTC_ADDRESS_REGISTER_B        11  // R/W

+#define RTC_ADDRESS_REGISTER_C        12  // RO

+#define RTC_ADDRESS_REGISTER_D        13  // RO

+#define RTC_ADDRESS_CENTURY           50  // R/W  Range 19..20 Bit 8 is R/W

+//

+// Date and time initial values.

+// They are used if the RTC values are invalid during driver initialization

+//

+#define RTC_INIT_SECOND 0

+#define RTC_INIT_MINUTE 0

+#define RTC_INIT_HOUR   0

+#define RTC_INIT_DAY    1

+#define RTC_INIT_MONTH  1

+#define RTC_INIT_YEAR   2001

+

+//

+// Register initial values

+//

+#define RTC_INIT_REGISTER_A 0x26

+#define RTC_INIT_REGISTER_B 0x02

+#define RTC_INIT_REGISTER_D 0x0

+

+#pragma pack(1)

+//

+// Register A

+//

+typedef struct {

+  UINT8 Rs : 4;   // Rate Selection Bits

+  UINT8 Dv : 3;   // Divisor

+  UINT8 Uip : 1;  // Update in progress

+} RTC_REGISTER_A_BITS;

+

+typedef union {

+  RTC_REGISTER_A_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_A;

+

+//

+// Register B

+//

+typedef struct {

+  UINT8 Dse : 1;  // 0 - Daylight saving disabled  1 - Daylight savings enabled

+  UINT8 Mil : 1;  // 0 - 12 hour mode              1 - 24 hour mode

+  UINT8 Dm : 1;   // 0 - BCD Format                1 - Binary Format

+  UINT8 Sqwe : 1; // 0 - Disable SQWE output       1 - Enable SQWE output

+  UINT8 Uie : 1;  // 0 - Update INT disabled       1 - Update INT enabled

+  UINT8 Aie : 1;  // 0 - Alarm INT disabled        1 - Alarm INT Enabled

+  UINT8 Pie : 1;  // 0 - Periodic INT disabled     1 - Periodic INT Enabled

+  UINT8 Set : 1;  // 0 - Normal operation.         1 - Updates inhibited

+} RTC_REGISTER_B_BITS;

+

+typedef union {

+  RTC_REGISTER_B_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_B;

+

+//

+// Register C

+//

+typedef struct {

+  UINT8 Reserved : 4; // Read as zero.  Can not be written.

+  UINT8 Uf : 1;       // Update End Interrupt Flag

+  UINT8 Af : 1;       // Alarm Interrupt Flag

+  UINT8 Pf : 1;       // Periodic Interrupt Flag

+  UINT8 Irqf : 1;     // Iterrupt Request Flag = PF & PIE | AF & AIE | UF & UIE

+} RTC_REGISTER_C_BITS;

+

+typedef union {

+  RTC_REGISTER_C_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_C;

+

+//

+// Register D

+//

+typedef struct {

+  UINT8 Reserved : 7; // Read as zero.  Can not be written.

+  UINT8 Vrt : 1;      // Valid RAM and Time

+} RTC_REGISTER_D_BITS;

+

+typedef union {

+  RTC_REGISTER_D_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_D;

+

+#pragma pack()

+

+/**

+  Initialize RTC.

+

+  @param  Global            For global use inside this module.

+

+  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.

+  @retval EFI_SUCCESS       Initialization successful.

+

+**/

+EFI_STATUS

+PcRtcInit (

+  IN PC_RTC_MODULE_GLOBALS  *Global

+  );

+

+/**

+  Sets the current local time and date information.

+

+  @param  Time                  A pointer to the current time.

+  @param  Global                For global use inside this module.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.

+

+**/

+EFI_STATUS

+PcRtcSetTime (

+  IN EFI_TIME               *Time,

+  IN PC_RTC_MODULE_GLOBALS  *Global

+  );

+

+/**

+  Returns the current time and date information, and the time-keeping capabilities

+  of the hardware platform.

+

+  @param  Time          A pointer to storage to receive a snapshot of the current time.

+  @param  Capabilities  An optional pointer to a buffer to receive the real time clock

+                        device's capabilities.

+  @param  Global        For global use inside this module.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER  Time is NULL.

+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.

+

+**/

+EFI_STATUS

+PcRtcGetTime (

+  OUT EFI_TIME              *Time,

+  OUT EFI_TIME_CAPABILITIES *Capabilities, OPTIONAL

+  IN  PC_RTC_MODULE_GLOBALS *Global

+  );

+

+/**

+  Sets the system wakeup alarm clock time.

+

+  @param  Enabled  Enable or disable the wakeup alarm.

+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.

+                   If Enable is FALSE, then this parameter is optional, and may be NULL.

+  @param  Global   For global use inside this module.

+

+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.

+                                If Enable is FALSE, then the wakeup alarm was disabled.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+PcRtcSetWakeupTime (

+  IN BOOLEAN                Enable,

+  IN EFI_TIME               *Time,  OPTIONAL

+  IN PC_RTC_MODULE_GLOBALS  *Global

+  );

+

+/**

+  Returns the current wakeup alarm clock setting.

+

+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.

+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.

+  @param  Time     The current alarm setting.

+  @param  Global   For global use inside this module.

+

+  @retval EFI_SUCCESS           The alarm settings were returned.

+  @retval EFI_INVALID_PARAMETER Enabled is NULL.

+  @retval EFI_INVALID_PARAMETER Pending is NULL.

+  @retval EFI_INVALID_PARAMETER Time is NULL.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+PcRtcGetWakeupTime (

+  OUT BOOLEAN               *Enabled,

+  OUT BOOLEAN               *Pending,

+  OUT EFI_TIME              *Time,

+  IN  PC_RTC_MODULE_GLOBALS *Global

+  );

+

+/**

+  The user Entry Point for PcRTC module.

+

+  This is the entrhy point for PcRTC module. It installs the UEFI runtime service

+  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().

+

+  @param  ImageHandle    The firmware allocated handle for the EFI image.

+  @param  SystemTable    A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS    The entry point is executed successfully.

+  @retval Others         Some error occurs when executing this entry point.

+

+**/

+EFI_STATUS

+EFIAPI

+InitializePcRtc (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  );

+

+/**

+  See if all fields of a variable of EFI_TIME type is correct.

+

+  @param   Time   The time to be checked.

+

+  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.

+  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.

+

+**/

+EFI_STATUS

+RtcTimeFieldsValid (

+  IN EFI_TIME *Time

+  );

+

+/**

+  Converts time from EFI_TIME format defined by UEFI spec to RTC's.

+

+  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.

+  If data mode of RTC is BCD, then converts EFI_TIME to it.

+  If RTC is in 12-hour format, then converts EFI_TIME to it.

+

+  @param   Time       On input, the time data read from UEFI to convert

+                      On output, the time converted to RTC format

+  @param   RegisterB  Value of Register B of RTC, indicating data mode

+  @param   Century    It is set according to EFI_TIME Time.

+

+**/

+VOID

+ConvertEfiTimeToRtcTime (

+  IN OUT EFI_TIME        *Time,

+  IN     RTC_REGISTER_B  RegisterB,

+  OUT    UINT8           *Century

+  );

+

+

+/**

+  Converts time read from RTC to EFI_TIME format defined by UEFI spec.

+

+  This function converts raw time data read from RTC to the EFI_TIME format

+  defined by UEFI spec.

+  If data mode of RTC is BCD, then converts it to decimal,

+  If RTC is in 12-hour format, then converts it to 24-hour format.

+

+  @param   Time       On input, the time data read from RTC to convert

+                      On output, the time converted to UEFI format

+  @param   Century    Value of century read from RTC.

+  @param   RegisterB  Value of Register B of RTC, indicating data mode

+                      and hour format.

+

+  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.

+  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.

+

+**/

+EFI_STATUS

+ConvertRtcTimeToEfiTime (

+  IN OUT EFI_TIME        *Time,

+  IN     UINT8           Century,

+  IN     RTC_REGISTER_B  RegisterB

+  );

+

+/**

+  Wait for a period for the RTC to be ready.

+

+  @param    Timeout  Tell how long it should take to wait.

+

+  @retval   EFI_DEVICE_ERROR   RTC device error.

+  @retval   EFI_SUCCESS        RTC is updated and ready.  

+**/

+EFI_STATUS

+RtcWaitToUpdate (

+  UINTN Timeout

+  );

+

+/**

+  See if field Day of an EFI_TIME is correct.

+

+  @param    Time   Its Day field is to be checked.

+

+  @retval   TRUE   Day field of Time is correct.

+  @retval   FALSE  Day field of Time is NOT correct.

+**/

+BOOLEAN

+DayValid (

+  IN  EFI_TIME  *Time

+  );

+

+/**

+  Check if it is a leapyear.

+

+  @param    Time   The time to be checked.

+

+  @retval   TRUE   It is a leapyear.

+  @retval   FALSE  It is NOT a leapyear.

+**/

+BOOLEAN

+IsLeapYear (

+  IN EFI_TIME   *Time

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.uni
new file mode 100644
index 0000000..8c61c4e
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c
new file mode 100644
index 0000000..9cf3988
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c
@@ -0,0 +1,156 @@
+/** @file

+  Provides Set/Get time operations.

+

+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/

+

+#include "PcRtc.h"

+

+PC_RTC_MODULE_GLOBALS  mModuleGlobal;

+

+EFI_HANDLE             mHandle = NULL;

+

+

+/**

+  Returns the current time and date information, and the time-keeping capabilities

+  of the hardware platform.

+

+  @param  Time          A pointer to storage to receive a snapshot of the current time.

+  @param  Capabilities  An optional pointer to a buffer to receive the real time

+                        clock device's capabilities.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER  Time is NULL.

+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+PcRtcEfiGetTime (

+  OUT EFI_TIME                *Time,

+  OUT EFI_TIME_CAPABILITIES   *Capabilities  OPTIONAL

+  )

+{

+  return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);

+}

+

+/**

+  Sets the current local time and date information.

+

+  @param  Time                   A pointer to the current time.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER  A time field is out of range.

+  @retval EFI_DEVICE_ERROR       The time could not be set due due to hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+PcRtcEfiSetTime (

+  IN EFI_TIME                *Time

+  )

+{

+  return PcRtcSetTime (Time, &mModuleGlobal);

+}

+

+/**

+  Returns the current wakeup alarm clock setting.

+

+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.

+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.

+  @param  Time     The current alarm setting.

+

+  @retval EFI_SUCCESS           The alarm settings were returned.

+  @retval EFI_INVALID_PARAMETER Enabled is NULL.

+  @retval EFI_INVALID_PARAMETER Pending is NULL.

+  @retval EFI_INVALID_PARAMETER Time is NULL.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+EFIAPI

+PcRtcEfiGetWakeupTime (

+  OUT BOOLEAN     *Enabled,

+  OUT BOOLEAN     *Pending,

+  OUT EFI_TIME    *Time

+  )

+{

+  return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);

+}

+

+

+/**

+  Sets the system wakeup alarm clock time.

+

+  @param  Enabled  Enable or disable the wakeup alarm.

+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.

+                   If Enable is FALSE, then this parameter is optional, and may be NULL.

+

+  @retval EFI_SUCCESS            If Enable is TRUE, then the wakeup alarm was enabled.

+                                 If Enable is FALSE, then the wakeup alarm was disabled.

+  @retval EFI_INVALID_PARAMETER  A time field is out of range.

+  @retval EFI_DEVICE_ERROR       The wakeup time could not be set due to a hardware error.

+  @retval EFI_UNSUPPORTED        A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+EFIAPI

+PcRtcEfiSetWakeupTime (

+  IN BOOLEAN      Enabled,

+  IN EFI_TIME    *Time       OPTIONAL

+  )

+{

+  return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);

+}

+

+/**

+  The user Entry Point for PcRTC module.

+

+  This is the entrhy point for PcRTC module. It installs the UEFI runtime service

+  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().

+

+  @param  ImageHandle    The firmware allocated handle for the EFI image.

+  @param  SystemTable    A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS    The entry point is executed successfully.

+  @retval Others         Some error occurs when executing this entry point.

+

+**/

+EFI_STATUS

+EFIAPI

+InitializePcRtc (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK);

+

+  Status = PcRtcInit (&mModuleGlobal);

+  ASSERT_EFI_ERROR (Status);

+

+  gRT->GetTime       = PcRtcEfiGetTime;

+  gRT->SetTime       = PcRtcEfiSetTime;

+  gRT->GetWakeupTime = PcRtcEfiGetWakeupTime;

+  gRT->SetWakeupTime = PcRtcEfiSetWakeupTime;

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &mHandle,

+                  &gEfiRealTimeClockArchProtocolGuid,

+                  NULL,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcExtra.uni
new file mode 100644
index 0000000..94f4514
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
new file mode 100644
index 0000000..9e5faf7
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
@@ -0,0 +1,69 @@
+## @file

+# PcRtc driver to install EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL.

+#

+# This driver provides GetTime, SetTime, GetWakeupTime, SetWakeupTime services to Runtime Service Table.

+# It will install a tagging protocol with gEfiRealTimeClockArchProtocolGuid.

+#

+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>

+# 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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PcRtc

+  MODULE_UNI_FILE                = PcRtc.uni

+  FILE_GUID                      = 378D7B65-8DA9-4773-B6E4-A47826A833E1

+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = InitializePcRtc

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 EBC

+#

+

+[Sources]

+  PcRtcEntry.c

+  PcRtc.c

+  PcRtc.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  PcAtChipsetPkg/PcAtChipsetPkg.dec

+

+[LibraryClasses]

+  UefiRuntimeServicesTableLib

+  UefiRuntimeLib

+  UefiBootServicesTableLib

+  UefiDriverEntryPoint

+  TimerLib

+  IoLib

+  BaseMemoryLib

+  UefiLib

+  DebugLib

+  BaseLib

+  PcdLib

+  ReportStatusCodeLib

+

+[Protocols]

+  gEfiRealTimeClockArchProtocolGuid             ## PRODUCES

+

+[Depex]

+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid

+  

+[Pcd]

+  gEfiMdeModulePkgTokenSpaceGuid.PcdRealTimeClockUpdateTimeout  ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear             ## CONSUMES

+  gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear             ## CONSUMES

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  PcRtcExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S
new file mode 100644
index 0000000..6b9c096
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.S
@@ -0,0 +1,133 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo8 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo8)

+ASM_PFX(IoReadFifo8):

+    push    %edi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %edi

+rep insb

+    pop     %edi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo16 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo16)

+ASM_PFX(IoReadFifo16):

+    push    %edi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %edi

+rep insw

+    pop     %edi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo32 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo32)

+ASM_PFX(IoReadFifo32):

+    push    %edi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %edi

+rep insl

+    pop     %edi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo8 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo8)

+ASM_PFX(IoWriteFifo8):

+    push    %esi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %esi

+rep outsb

+    pop     %esi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo16 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo16)

+ASM_PFX(IoWriteFifo16):

+    push    %esi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %esi

+rep outsw

+    pop     %esi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo32 (

+#    IN UINTN                  Port,

+#    IN UINTN                  Count,

+#    IN VOID                   *Buffer

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo32)

+ASM_PFX(IoWriteFifo32):

+    push    %esi

+    cld

+    movw    8(%esp), %dx

+    mov     12(%esp), %ecx

+    mov     16(%esp), %esi

+rep outsl

+    pop     %esi

+    ret

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm
new file mode 100644
index 0000000..4b147cb
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/Ia32/IoFifo.asm
@@ -0,0 +1,139 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+; 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.

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo8 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo8 PROC

+    push    edi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 16]

+rep insb

+    pop     edi

+    ret

+IoReadFifo8 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo16 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo16 PROC

+    push    edi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 16]

+rep insw

+    pop     edi

+    ret

+IoReadFifo16 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo32 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo32 PROC

+    push    edi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 16]

+rep insd

+    pop     edi

+    ret

+IoReadFifo32 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo8 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo8 PROC

+    push    esi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     esi, [esp + 16]

+rep outsb

+    pop     esi

+    ret

+IoWriteFifo8 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo16 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo16 PROC

+    push    esi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     esi, [esp + 16]

+rep outsw

+    pop     esi

+    ret

+IoWriteFifo16 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo32 (

+;    IN UINTN                  Port,

+;    IN UINTN                  Size,

+;    IN VOID                   *Buffer

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo32 PROC

+    push    esi

+    cld

+    mov     dx, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     esi, [esp + 16]

+rep outsd

+    pop     esi

+    ret

+IoWriteFifo32 ENDP

+

+    END

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h
new file mode 100644
index 0000000..5d48bf5
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/IoFifo.h
@@ -0,0 +1,175 @@
+/** @file

+  I/O FIFO routines

+

+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/ 

+

+#ifndef _IO_FIFO_H_INCLUDED_

+#define _IO_FIFO_H_INCLUDED_

+

+/**

+  Reads an 8-bit I/O port fifo into a block of memory.

+

+  Reads the 8-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Reads a 16-bit I/O port fifo into a block of memory.

+

+  Reads the 16-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Reads a 32-bit I/O port fifo into a block of memory.

+

+  Reads the 32-bit I/O fifo port specified by Port.

+

+  The port is read Count times, and the read data is

+  stored in the provided Buffer.

+

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to read.

+  @param  Count   The number of times to read I/O port.

+  @param  Buffer  The buffer to store the read data into.

+

+**/

+VOID

+EFIAPI

+IoReadFifo32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Writes a block of memory into an 8-bit I/O port fifo.

+

+  Writes the 8-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Writes a block of memory into a 16-bit I/O port fifo.

+

+  Writes the 16-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+/**

+  Writes a block of memory into a 32-bit I/O port fifo.

+

+  Writes the 32-bit I/O fifo port specified by Port.

+

+  The port is written Count times, and the write data is

+  retrieved from the provided Buffer.

+

+  This function must guarantee that all I/O write and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  Count   The number of times to write I/O port.

+  @param  Buffer  The buffer to store the write data into.

+

+**/

+VOID

+EFIAPI

+IoWriteFifo32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     Count,

+  OUT     VOID                      *Buffer

+  );

+

+#endif

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.c b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.c
new file mode 100644
index 0000000..83fcdf4
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.c
@@ -0,0 +1,1200 @@
+/** @file

+  Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation

+

+Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/ 

+

+#include "PciHostBridge.h"

+

+//

+// Hard code: Root Bridge Number within the host bridge

+//            Root Bridge's attribute

+//            Root Bridge's device path

+//            Root Bridge's resource appeture

+//

+UINTN RootBridgeNumber[1] = { 1 };

+

+UINT64 RootBridgeAttribute[1][1] = { { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM } };

+

+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[1][1] = {

+  {

+    {

+      {

+        {

+          ACPI_DEVICE_PATH,

+          ACPI_DP,

+          {

+            (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),

+            (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)

+          }

+        },

+        EISA_PNP_ID(0x0A03),

+        0

+      },

+  

+      {

+        END_DEVICE_PATH_TYPE,

+        END_ENTIRE_DEVICE_PATH_SUBTYPE,

+        {

+          END_DEVICE_PATH_LENGTH,

+          0

+        }

+      }

+    }

+  }

+};

+

+PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[1][1] = {

+  {{0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}}

+};

+

+EFI_HANDLE mDriverImageHandle;

+

+PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {

+  PCI_HOST_BRIDGE_SIGNATURE,  // Signature

+  NULL,                       // HostBridgeHandle

+  0,                          // RootBridgeNumber

+  {NULL, NULL},               // Head

+  FALSE,                      // ResourceSubiteed

+  TRUE,                       // CanRestarted

+  {

+    NotifyPhase,

+    GetNextRootBridge,

+    GetAttributes,

+    StartBusEnumeration,

+    SetBusNumbers,

+    SubmitResources,

+    GetProposedResources,

+    PreprocessController

+  }

+};

+

+//

+// Implementation

+//

+

+/**

+  Entry point of this driver

+

+  @param ImageHandle     Handle of driver image

+  @param SystemTable     Point to EFI_SYSTEM_TABLE

+

+  @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource

+  @retval EFI_DEVICE_ERROR      Can not install the protocol instance

+  @retval EFI_SUCCESS           Success to initialize the Pci host bridge.

+**/

+EFI_STATUS

+EFIAPI

+InitializePciHostBridge (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                  Status;

+  UINTN                       Loop1;

+  UINTN                       Loop2;

+  PCI_HOST_BRIDGE_INSTANCE    *HostBridge;

+  PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;

+ 

+  mDriverImageHandle = ImageHandle;

+  

+  //

+  // Create Host Bridge Device Handle

+  //

+  for (Loop1 = 0; Loop1 < HOST_BRIDGE_NUMBER; Loop1++) {

+    HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);

+    if (HostBridge == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+  

+    HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];

+    InitializeListHead (&HostBridge->Head);

+

+    Status = gBS->InstallMultipleProtocolInterfaces (

+                    &HostBridge->HostBridgeHandle,              

+                    &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,

+                    NULL

+                    );

+    if (EFI_ERROR (Status)) {

+      FreePool (HostBridge);

+      return EFI_DEVICE_ERROR;

+    }

+  

+    //

+    // Create Root Bridge Device Handle in this Host Bridge

+    //

+  

+    for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {

+      PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));

+      if (PrivateData == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;

+      PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];

+

+      RootBridgeConstructor (

+        &PrivateData->Io, 

+        HostBridge->HostBridgeHandle, 

+        RootBridgeAttribute[Loop1][Loop2], 

+        &mResAppeture[Loop1][Loop2]

+        );

+    

+      Status = gBS->InstallMultipleProtocolInterfaces(

+                      &PrivateData->Handle,              

+                      &gEfiDevicePathProtocolGuid,      PrivateData->DevicePath,

+                      &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,

+                      NULL

+                      );

+      if (EFI_ERROR (Status)) {

+        FreePool(PrivateData);

+        return EFI_DEVICE_ERROR;

+      }

+ 

+      InsertTailList (&HostBridge->Head, &PrivateData->Link);

+    }

+  } 

+

+  return EFI_SUCCESS;

+}

+

+

+/**

+   These are the notifications from the PCI bus driver that it is about to enter a certain

+   phase of the PCI enumeration process.

+

+   This member function can be used to notify the host bridge driver to perform specific actions,

+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.

+   Eight notification points are defined at this time. See belows:

+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data

+                                          structures. The PCI enumerator should issue this notification

+                                          before starting a fresh enumeration process. Enumeration cannot

+                                          be restarted after sending any other notification such as

+                                          EfiPciHostBridgeBeginBusAllocation.

+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is

+                                          required here. This notification can be used to perform any

+                                          chipset-specific programming.

+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No

+                                          specific action is required here. This notification can be used to

+                                          perform any chipset-specific programming.

+   EfiPciHostBridgeBeginResourceAllocation

+                                          The resource allocation phase is about to begin. No specific

+                                          action is required here. This notification can be used to perform

+                                          any chipset-specific programming.

+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI

+                                          root bridges. These resource settings are returned on the next call to

+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of

+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible

+                                          for gathering I/O and memory requests for

+                                          all the PCI root bridges and submitting these requests using

+                                          SubmitResources(). This function pads the resource amount

+                                          to suit the root bridge hardware, takes care of dependencies between

+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)

+                                          with the allocation request. In the case of padding, the allocated range

+                                          could be bigger than what was requested.

+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated

+                                          resources (proposed resources) for all the PCI root bridges. After the

+                                          hardware is programmed, reassigning resources will not be supported.

+                                          The bus settings are not affected.

+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI

+                                          root bridges and resets the I/O and memory apertures to their initial

+                                          state. The bus settings are not affected. If the request to allocate

+                                          resources fails, the PCI enumerator can use this notification to

+                                          deallocate previous resources, adjust the requests, and retry

+                                          allocation.

+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is

+                                          required here. This notification can be used to perform any chipsetspecific

+                                          programming.

+

+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in] Phase               The phase during enumeration

+

+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error

+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if

+                                  SubmitResources() has not been called for one or more

+                                  PCI root bridges before this call

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid

+                                  for a Phase of EfiPciHostBridgeSetResources.

+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the

+                                  previously submitted resource requests cannot be fulfilled or

+                                  were only partially fulfilled.

+   @retval EFI_SUCCESS            The notification was accepted without any errors.

+

+**/

+EFI_STATUS

+EFIAPI

+NotifyPhase(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase

+  )

+{

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  PCI_RESOURCE_TYPE                     Index;

+  LIST_ENTRY                            *List;

+  EFI_PHYSICAL_ADDRESS                  BaseAddress;

+  UINT64                                AddrLen;

+  UINTN                                 BitsOfAlignment;

+  EFI_STATUS                            Status;

+  EFI_STATUS                            ReturnStatus;

+  

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  

+  switch (Phase) {

+

+  case EfiPciHostBridgeBeginEnumeration:

+    if (HostBridgeInstance->CanRestarted) {

+      //

+      // Reset the Each Root Bridge 

+      //

+      List = HostBridgeInstance->Head.ForwardLink;

+  

+      while (List != &HostBridgeInstance->Head) {

+        RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+        for (Index = TypeIo; Index < TypeMax; Index++) {

+          RootBridgeInstance->ResAllocNode[Index].Type      = Index;

+          RootBridgeInstance->ResAllocNode[Index].Base      = 0;

+          RootBridgeInstance->ResAllocNode[Index].Length    = 0;

+          RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;

+        }

+          

+        List = List->ForwardLink;

+      }

+        

+      HostBridgeInstance->ResourceSubmited = FALSE;

+      HostBridgeInstance->CanRestarted     = TRUE;

+    } else {

+      //

+      // Can not restart

+      // 

+      return EFI_NOT_READY;

+    }  

+    break;

+

+  case EfiPciHostBridgeEndEnumeration:

+    break;

+

+  case EfiPciHostBridgeBeginBusAllocation:

+    //

+    // No specific action is required here, can perform any chipset specific programing

+    //

+    HostBridgeInstance->CanRestarted = FALSE;

+    break;

+

+  case EfiPciHostBridgeEndBusAllocation:

+    //

+    // No specific action is required here, can perform any chipset specific programing

+    //

+    //HostBridgeInstance->CanRestarted = FALSE;

+    break;

+

+  case EfiPciHostBridgeBeginResourceAllocation:

+    //

+    // No specific action is required here, can perform any chipset specific programing

+    //

+    //HostBridgeInstance->CanRestarted = FALSE;

+    break;

+

+  case EfiPciHostBridgeAllocateResources:

+    ReturnStatus = EFI_SUCCESS;

+    if (HostBridgeInstance->ResourceSubmited) {

+      //

+      // Take care of the resource dependencies between the root bridges 

+      //

+      List = HostBridgeInstance->Head.ForwardLink;

+

+      while (List != &HostBridgeInstance->Head) {

+        RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+        for (Index = TypeIo; Index < TypeBus; Index++) {

+          if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+                                        

+            AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+            

+            //

+            // Get the number of '1' in Alignment.

+            //

+            BitsOfAlignment = (UINTN) (HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1);

+                                  

+            switch (Index) {

+

+              case TypeIo:  

+                //

+                // It is impossible for this chipset to align 0xFFFF for IO16

+                // So clear it

+                //

+                if (BitsOfAlignment >= 16) {

+                  BitsOfAlignment = 0;

+                }

+                  

+                Status = gDS->AllocateIoSpace (

+                                EfiGcdAllocateAnySearchBottomUp, 

+                                EfiGcdIoTypeIo, 

+                                BitsOfAlignment,

+                                AddrLen,

+                                &BaseAddress,

+                                mDriverImageHandle,

+                                NULL

+                                );

+                 

+                if (!EFI_ERROR (Status)) {

+                  RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;

+                  RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated; 

+                } else {

+                  ReturnStatus = Status;  

+                  if (Status != EFI_OUT_OF_RESOURCES) {

+                    RootBridgeInstance->ResAllocNode[Index].Length = 0;

+                  }

+                }

+

+                break;

+

+

+              case TypeMem32:

+                //

+                // It is impossible for this chipset to align 0xFFFFFFFF for Mem32

+                // So clear it 

+                //

+                  

+                if (BitsOfAlignment >= 32) {

+                  BitsOfAlignment = 0;

+                }

+                  

+                Status = gDS->AllocateMemorySpace (

+                                EfiGcdAllocateAnySearchBottomUp, 

+                                EfiGcdMemoryTypeMemoryMappedIo, 

+                                BitsOfAlignment,

+                                AddrLen,

+                                &BaseAddress,

+                                mDriverImageHandle,

+                                NULL

+                                );

+                  

+                if (!EFI_ERROR (Status)) {

+                  // We were able to allocate the PCI memory

+                  RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;

+                  RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;

+                    

+                } else {

+                  // Not able to allocate enough PCI memory

+                  ReturnStatus = Status;  

+                    

+                  if (Status != EFI_OUT_OF_RESOURCES) {

+                    RootBridgeInstance->ResAllocNode[Index].Length = 0;

+                  } 

+                  ASSERT (FALSE);

+                }

+                break;

+                  

+              case TypePMem32:                  

+              case TypeMem64:                  

+              case TypePMem64:

+                  ReturnStatus = EFI_ABORTED;

+                  break;  

+              default:

+                ASSERT (FALSE);

+                break;

+              }; //end switch

+          }

+        }

+          

+        List = List->ForwardLink;

+      }

+        

+      return ReturnStatus;

+

+    } else {

+      return EFI_NOT_READY;

+    }

+    break;

+

+  case EfiPciHostBridgeSetResources:

+    break;

+

+  case EfiPciHostBridgeFreeResources:

+    ReturnStatus = EFI_SUCCESS;

+    List = HostBridgeInstance->Head.ForwardLink;

+    while (List != &HostBridgeInstance->Head) {

+      RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+      for (Index = TypeIo; Index < TypeBus; Index++) {

+        if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {

+          AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+          BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;

+          switch (Index) {

+

+          case TypeIo:  

+            Status = gDS->FreeIoSpace (BaseAddress, AddrLen);                

+            if (EFI_ERROR (Status)) {

+              ReturnStatus = Status;

+            }

+            break;

+

+          case TypeMem32:

+            Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);

+            if (EFI_ERROR (Status)) {

+              ReturnStatus = Status;

+            }

+            break;

+

+          case TypePMem32:

+            break;

+

+          case TypeMem64:

+            break;

+

+          case TypePMem64:

+            break; 

+

+          default:

+            ASSERT (FALSE);

+            break;

+

+          }; //end switch

+          RootBridgeInstance->ResAllocNode[Index].Type      = Index;

+          RootBridgeInstance->ResAllocNode[Index].Base      = 0;

+          RootBridgeInstance->ResAllocNode[Index].Length    = 0;

+          RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;

+        }

+      }

+        

+      List = List->ForwardLink;

+    }

+              

+    HostBridgeInstance->ResourceSubmited = FALSE;

+    HostBridgeInstance->CanRestarted     = TRUE;      

+    return ReturnStatus;

+

+  case EfiPciHostBridgeEndResourceAllocation:

+    HostBridgeInstance->CanRestarted = FALSE;

+    break;

+

+  default:

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  return EFI_SUCCESS;  

+}

+

+/**

+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.

+

+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that

+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI

+   root bridges. On each call, the handle that was returned by the previous call is passed into the

+   interface, and on output the interface returns the device handle of the next PCI root bridge. The

+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+   for that root bridge. When there are no more PCI root bridges to report, the interface returns

+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they

+   are returned by this function.

+   For D945 implementation, there is only one root bridge in PCI host bridge.

+

+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.

+   

+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the

+                                  specific Host bridge and return EFI_SUCCESS. 

+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was

+                                  returned on a previous call to GetNextRootBridge().

+**/

+EFI_STATUS

+EFIAPI

+GetNextRootBridge(

+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN OUT   EFI_HANDLE                                       *RootBridgeHandle

+  )

+{

+  BOOLEAN                               NoRootBridge; 

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  

+  NoRootBridge = TRUE;

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  

+  while (List != &HostBridgeInstance->Head) {

+    NoRootBridge = FALSE;

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (*RootBridgeHandle == NULL) {

+      //

+      // Return the first Root Bridge Handle of the Host Bridge

+      //

+      *RootBridgeHandle = RootBridgeInstance->Handle;

+      return EFI_SUCCESS;

+    } else {

+      if (*RootBridgeHandle == RootBridgeInstance->Handle) {

+        //

+        // Get next if have

+        //

+        List = List->ForwardLink;

+        if (List!=&HostBridgeInstance->Head) {

+          RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+          *RootBridgeHandle = RootBridgeInstance->Handle;

+          return EFI_SUCCESS;  

+        } else {

+          return EFI_NOT_FOUND;

+        }

+      }

+    }

+      

+    List = List->ForwardLink;

+  } //end while

+  

+  if (NoRootBridge) {

+    return EFI_NOT_FOUND;

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+}

+

+/**

+   Returns the allocation attributes of a PCI root bridge.

+

+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary

+   from one PCI root bridge to another. These attributes are different from the decode-related

+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The

+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device

+   handles of all the root bridges that are associated with this host bridge must be obtained by calling

+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or

+   after the enumeration process. The hardware may provide mechanisms to change the attributes on

+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is 

+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in

+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.

+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to 

+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any 

+   prefetchable memory.

+      Attribute                                 Description

+   ------------------------------------         ----------------------------------------------------------------------

+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate

+                                                windows for nonprefetchable and prefetchable memory. A PCI bus

+                                                driver needs to include requests for prefetchable memory in the

+                                                nonprefetchable memory pool.

+

+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory

+                                                windows. If this bit is not set, the PCI bus driver needs to include

+                                                requests for a 64-bit memory address in the corresponding 32-bit

+                                                memory pool.

+

+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type

+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter

+   

+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL

+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.

+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.

+

+**/

+EFI_STATUS

+EFIAPI

+GetAttributes(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT UINT64                                           *Attributes

+  )

+{

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  

+  if (Attributes == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      *Attributes = RootBridgeInstance->RootBridgeAttrib;

+      return EFI_SUCCESS;

+    }

+    List = List->ForwardLink;

+  }

+  

+  //

+  // RootBridgeHandle is not an EFI_HANDLE 

+  // that was returned on a previous call to GetNextRootBridge()

+  //

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+   Sets up the specified PCI root bridge for the bus enumeration process.

+

+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range

+   over which the search should be performed in ACPI 2.0 resource descriptor format.

+

+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.

+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.

+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.

+   

+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle

+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.

+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.

+

+**/

+EFI_STATUS

+EFIAPI

+StartBusEnumeration(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT VOID                                             **Configuration

+  )

+{

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  VOID                                  *Buffer;

+  UINT8                                 *Temp;

+  UINT64                                BusStart;

+  UINT64                                BusEnd;

+  

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      //

+      // Set up the Root Bridge for Bus Enumeration

+      //

+      BusStart = RootBridgeInstance->BusBase;

+      BusEnd   = RootBridgeInstance->BusLimit;

+      //

+      // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR

+      //

+      

+      Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));

+      if (Buffer == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+      

+      Temp = (UINT8 *)Buffer;

+      

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = 0x2B;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0; 

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;       

+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;

+      

+      Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;      

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;

+      

+      *Configuration = Buffer;      

+      return EFI_SUCCESS;

+    }

+    List = List->ForwardLink;

+  }

+  

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.

+

+   This member function programs the specified PCI root bridge to decode the bus range that is

+   specified by the input parameter Configuration.

+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.

+

+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed

+   @param[in] Configuration     The pointer to the PCI bus resource descriptor

+   

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than 

+                                  bus descriptors.

+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.

+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.

+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+SetBusNumbers(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_HANDLE                                       RootBridgeHandle,

+  IN VOID                                             *Configuration

+  )

+{

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  UINT8                                 *Ptr;

+  UINTN                                 BusStart;

+  UINTN                                 BusEnd;

+  UINTN                                 BusLen;

+  

+  if (Configuration == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+    

+  Ptr = Configuration;

+  

+  //

+  // Check the Configuration is valid

+  //

+  if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {

+    return EFI_INVALID_PARAMETER;

+  }

+   

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  Ptr = Configuration;

+  

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;

+      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;

+      BusEnd = BusStart + BusLen - 1;

+      

+      if (BusStart > BusEnd) {

+        return EFI_INVALID_PARAMETER;

+      }

+      

+      if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {

+        return EFI_INVALID_PARAMETER;

+      }

+      

+      //

+      // Update the Bus Range

+      //

+      RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;

+      RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;

+      RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;

+      

+      //

+      // Program the Root Bridge Hardware

+      //

+       

+      return EFI_SUCCESS;

+    }

+    

+    List = List->ForwardLink;

+  }

+  

+  return EFI_INVALID_PARAMETER;

+}

+

+

+/**

+   Submits the I/O and memory resource requirements for the specified PCI root bridge.

+

+   This function is used to submit all the I/O and memory resources that are required by the specified

+   PCI root bridge. The input parameter Configuration is used to specify the following:

+   - The various types of resources that are required

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.

+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.

+   

+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are 

+                                  not supported by this PCI root bridge. This error will happen if the caller 

+                                  did not combine resources according to Attributes that were returned by

+                                  GetAllocAttributes().

+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.

+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.

+

+**/

+EFI_STATUS

+EFIAPI

+SubmitResources(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_HANDLE                                       RootBridgeHandle,

+  IN VOID                                             *Configuration

+  )

+{

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  UINT8                                 *Temp;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;

+  UINT64                                AddrLen;

+  UINT64                                Alignment;

+  

+  //

+  // Check the input parameter: Configuration

+  //

+  if (Configuration == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  Temp = (UINT8 *)Configuration;

+  while ( *Temp == 0x8A) { 

+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;

+  }

+  if (*Temp != 0x79) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  Temp = (UINT8 *)Configuration;

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      while ( *Temp == 0x8A) {

+        Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;

+

+        //

+        // Check Address Length

+        //

+        if (Ptr->AddrLen > 0xffffffff) {

+          return EFI_INVALID_PARAMETER;

+        }

+

+        //

+        // Check address range alignment

+        //

+        if (Ptr->AddrRangeMax >= 0xffffffff || Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {

+          return EFI_INVALID_PARAMETER;

+        }

+        

+        switch (Ptr->ResType) {

+

+        case 0:

+            

+          //

+          // Check invalid Address Sapce Granularity

+          //

+          if (Ptr->AddrSpaceGranularity != 32) {

+            return EFI_INVALID_PARAMETER;

+          }

+            

+          //

+          // check the memory resource request is supported by PCI root bridge

+          //

+          if (RootBridgeInstance->RootBridgeAttrib == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM &&

+               Ptr->SpecificFlag == 0x06) {

+            return EFI_INVALID_PARAMETER;

+          }

+            

+          AddrLen = Ptr->AddrLen;

+          Alignment = Ptr->AddrRangeMax;

+          if (Ptr->AddrSpaceGranularity == 32) {

+            if (Ptr->SpecificFlag == 0x06) {

+              //

+              // Apply from GCD

+              //

+              RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;

+            } else {

+              RootBridgeInstance->ResAllocNode[TypeMem32].Length = AddrLen;

+              RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;

+              RootBridgeInstance->ResAllocNode[TypeMem32].Status = ResRequested; 

+              HostBridgeInstance->ResourceSubmited = TRUE;

+            }

+          }

+

+          if (Ptr->AddrSpaceGranularity == 64) {

+            if (Ptr->SpecificFlag == 0x06) {

+              RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;

+            } else {

+              RootBridgeInstance->ResAllocNode[TypeMem64].Status = ResSubmitted;

+            }

+          }

+          break;

+

+        case 1:

+          AddrLen = (UINTN) Ptr->AddrLen;

+          Alignment = (UINTN) Ptr->AddrRangeMax;

+          RootBridgeInstance->ResAllocNode[TypeIo].Length  = AddrLen;

+          RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;

+          RootBridgeInstance->ResAllocNode[TypeIo].Status  = ResRequested;

+          HostBridgeInstance->ResourceSubmited = TRUE; 

+          break;

+

+        default:

+            break;

+        };

+    

+        Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;

+      } 

+      

+      return EFI_SUCCESS;

+    }

+    

+    List = List->ForwardLink;

+  }

+  

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+   Returns the proposed resource settings for the specified PCI root bridge.

+

+   This member function returns the proposed resource settings for the specified PCI root bridge. The

+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of

+   EfiPciHostBridgeAllocateResources. The output parameter Configuration

+   specifies the following:

+   - The various types of resources, excluding bus resources, that are allocated

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.

+   

+   @retval EFI_SUCCESS            The requested parameters were returned.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+GetProposedResources(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT VOID                                             **Configuration

+  )

+{

+  LIST_ENTRY                            *List; 

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  UINTN                                 Index;

+  UINTN                                 Number; 

+  VOID                                  *Buffer; 

+  UINT8                                 *Temp;

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;

+  UINT64                                ResStatus;

+    

+  Buffer = NULL;

+  Number = 0;

+  //

+  // Get the Host Bridge Instance from the resource allocation protocol

+  //

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+  

+  //

+  // Enumerate the root bridges in this host bridge

+  //

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      for (Index = 0; Index < TypeBus; Index ++) {

+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+          Number ++;

+        }  

+      }

+      

+      if (Number ==  0) {

+        return EFI_INVALID_PARAMETER;

+      }

+

+      Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));

+      if (Buffer == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+      

+      Temp = Buffer;

+      for (Index = 0; Index < TypeBus; Index ++) {

+        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {

+          Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;

+          ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;

+          

+          switch (Index) {

+

+          case TypeIo:

+            //

+            // Io

+            //

+            Ptr->Desc = 0x8A;

+            Ptr->Len  = 0x2B;

+            Ptr->ResType = 1;

+            Ptr->GenFlag = 0; 

+            Ptr->SpecificFlag = 0;

+            Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;

+            Ptr->AddrRangeMax = 0;

+            Ptr->AddrTranslationOffset = \

+                 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;

+            Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+            break;

+

+          case TypeMem32:

+            //

+            // Memory 32

+            // 

+            Ptr->Desc = 0x8A;

+            Ptr->Len  = 0x2B;

+            Ptr->ResType = 0;

+            Ptr->GenFlag = 0; 

+            Ptr->SpecificFlag = 0;

+            Ptr->AddrSpaceGranularity = 32;

+            Ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;

+            Ptr->AddrRangeMax = 0;

+            Ptr->AddrTranslationOffset = \

+                 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;              

+            Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;

+            break;

+

+          case TypePMem32:

+            //

+            // Prefetch memory 32

+            //

+            Ptr->Desc = 0x8A;

+            Ptr->Len  = 0x2B;

+            Ptr->ResType = 0;

+            Ptr->GenFlag = 0; 

+            Ptr->SpecificFlag = 6;

+            Ptr->AddrSpaceGranularity = 32;

+            Ptr->AddrRangeMin = 0;

+            Ptr->AddrRangeMax = 0;

+            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;       

+            Ptr->AddrLen = 0;

+            break;

+

+          case TypeMem64:

+            //

+            // Memory 64

+            //

+            Ptr->Desc = 0x8A;

+            Ptr->Len  = 0x2B;

+            Ptr->ResType = 0;

+            Ptr->GenFlag = 0; 

+            Ptr->SpecificFlag = 0;

+            Ptr->AddrSpaceGranularity = 64;

+            Ptr->AddrRangeMin = 0;

+            Ptr->AddrRangeMax = 0;

+            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;       

+            Ptr->AddrLen = 0;

+            break;

+

+          case TypePMem64:

+            //

+            // Prefetch memory 64

+            //

+            Ptr->Desc = 0x8A;

+            Ptr->Len  = 0x2B;

+            Ptr->ResType = 0;

+            Ptr->GenFlag = 0; 

+            Ptr->SpecificFlag = 6;

+            Ptr->AddrSpaceGranularity = 64;

+            Ptr->AddrRangeMin = 0;

+            Ptr->AddrRangeMax = 0;

+            Ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;       

+            Ptr->AddrLen = 0;

+            break;

+          };

+          

+          Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);

+        }  

+      }

+      

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;      

+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;

+      

+      *Configuration = Buffer;      

+       

+      return EFI_SUCCESS;

+    }

+    

+    List = List->ForwardLink;

+  }

+  

+  return EFI_INVALID_PARAMETER;

+}

+

+/**

+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various

+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual

+   PCI controllers before enumeration.

+

+   This function is called during the PCI enumeration process. No specific action is expected from this

+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before

+   enumeration.

+

+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in

+                            InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the

+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI

+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for

+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.

+   @param Phase             The phase of the PCI device enumeration. 

+   

+   @retval EFI_SUCCESS              The requested parameters were returned.

+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in

+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.

+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should

+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI

+                                    bridge.

+

+**/

+EFI_STATUS

+EFIAPI

+PreprocessController (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,

+  IN  EFI_HANDLE                                                RootBridgeHandle,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase

+  )

+{

+  PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;

+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;

+  LIST_ENTRY                            *List; 

+

+  HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);

+  List = HostBridgeInstance->Head.ForwardLink;

+

+  //

+  // Enumerate the root bridges in this host bridge

+  //

+  while (List != &HostBridgeInstance->Head) {

+    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);

+    if (RootBridgeHandle == RootBridgeInstance->Handle) {

+      break;

+    }

+    List = List->ForwardLink;

+  }

+  if (List == &HostBridgeInstance->Head) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.h b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.h
new file mode 100644
index 0000000..f819829
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.h
@@ -0,0 +1,498 @@
+/** @file

+  The Header file of the Pci Host Bridge Driver 

+

+  Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>

+  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.

+

+**/ 

+

+#ifndef _PCI_HOST_BRIDGE_H_

+#define _PCI_HOST_BRIDGE_H_

+

+#include <PiDxe.h>

+

+#include <IndustryStandard/Pci.h>

+#include <IndustryStandard/Acpi.h>

+

+#include <Protocol/PciHostBridgeResourceAllocation.h>

+#include <Protocol/PciRootBridgeIo.h>

+#include <Protocol/Metronome.h>

+#include <Protocol/DevicePath.h>

+

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/IoLib.h>

+#include <Library/PciLib.h>

+

+//

+// Hard code the host bridge number in the platform.

+// In this chipset, there is only one host bridge.

+//

+#define HOST_BRIDGE_NUMBER  1

+

+#define MAX_PCI_DEVICE_NUMBER      31

+#define MAX_PCI_FUNCTION_NUMBER    7

+#define MAX_PCI_REG_ADDRESS        0xFF

+

+typedef enum {

+  IoOperation,

+  MemOperation,

+  PciOperation

+} OPERATION_TYPE;

+

+#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')

+typedef struct {

+  UINTN                                             Signature;

+  EFI_HANDLE                                        HostBridgeHandle;

+  UINTN                                             RootBridgeNumber;

+  LIST_ENTRY                                        Head;

+  BOOLEAN                                           ResourceSubmited;  

+  BOOLEAN                                           CanRestarted;  

+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  ResAlloc;

+} PCI_HOST_BRIDGE_INSTANCE;

+

+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \

+  CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)

+  

+//

+//  HostBridge Resource Allocation interface

+//

+

+/**

+   These are the notifications from the PCI bus driver that it is about to enter a certain

+   phase of the PCI enumeration process.

+

+   This member function can be used to notify the host bridge driver to perform specific actions,

+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.

+   Eight notification points are defined at this time. See belows:

+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data

+                                          structures. The PCI enumerator should issue this notification

+                                          before starting a fresh enumeration process. Enumeration cannot

+                                          be restarted after sending any other notification such as

+                                          EfiPciHostBridgeBeginBusAllocation.

+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is

+                                          required here. This notification can be used to perform any

+                                          chipset-specific programming.

+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No

+                                          specific action is required here. This notification can be used to

+                                          perform any chipset-specific programming.

+   EfiPciHostBridgeBeginResourceAllocation

+                                          The resource allocation phase is about to begin. No specific

+                                          action is required here. This notification can be used to perform

+                                          any chipset-specific programming.

+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI

+                                          root bridges. These resource settings are returned on the next call to

+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of

+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible

+                                          for gathering I/O and memory requests for

+                                          all the PCI root bridges and submitting these requests using

+                                          SubmitResources(). This function pads the resource amount

+                                          to suit the root bridge hardware, takes care of dependencies between

+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)

+                                          with the allocation request. In the case of padding, the allocated range

+                                          could be bigger than what was requested.

+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated

+                                          resources (proposed resources) for all the PCI root bridges. After the

+                                          hardware is programmed, reassigning resources will not be supported.

+                                          The bus settings are not affected.

+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI

+                                          root bridges and resets the I/O and memory apertures to their initial

+                                          state. The bus settings are not affected. If the request to allocate

+                                          resources fails, the PCI enumerator can use this notification to

+                                          deallocate previous resources, adjust the requests, and retry

+                                          allocation.

+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is

+                                          required here. This notification can be used to perform any chipsetspecific

+                                          programming.

+

+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in] Phase               The phase during enumeration

+

+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error

+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if

+                                  SubmitResources() has not been called for one or more

+                                  PCI root bridges before this call

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid

+                                  for a Phase of EfiPciHostBridgeSetResources.

+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the

+                                  previously submitted resource requests cannot be fulfilled or

+                                  were only partially fulfilled.

+   @retval EFI_SUCCESS            The notification was accepted without any errors.

+

+**/

+EFI_STATUS

+EFIAPI

+NotifyPhase(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase

+  );

+

+/**

+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.

+

+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that

+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI

+   root bridges. On each call, the handle that was returned by the previous call is passed into the

+   interface, and on output the interface returns the device handle of the next PCI root bridge. The

+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+   for that root bridge. When there are no more PCI root bridges to report, the interface returns

+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they

+   are returned by this function.

+   For D945 implementation, there is only one root bridge in PCI host bridge.

+

+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.

+   

+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the

+                                  specific Host bridge and return EFI_SUCCESS. 

+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was

+                                  returned on a previous call to GetNextRootBridge().

+**/

+EFI_STATUS

+EFIAPI

+GetNextRootBridge(

+  IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN OUT   EFI_HANDLE                                       *RootBridgeHandle

+  );

+  

+/**

+   Returns the allocation attributes of a PCI root bridge.

+

+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary

+   from one PCI root bridge to another. These attributes are different from the decode-related

+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The

+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device

+   handles of all the root bridges that are associated with this host bridge must be obtained by calling

+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or

+   after the enumeration process. The hardware may provide mechanisms to change the attributes on

+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is 

+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in

+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.

+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to 

+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any 

+   prefetchable memory.

+      Attribute                                 Description

+   ------------------------------------         ----------------------------------------------------------------------

+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate

+                                                windows for nonprefetchable and prefetchable memory. A PCI bus

+                                                driver needs to include requests for prefetchable memory in the

+                                                nonprefetchable memory pool.

+

+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory

+                                                windows. If this bit is not set, the PCI bus driver needs to include

+                                                requests for a 64-bit memory address in the corresponding 32-bit

+                                                memory pool.

+

+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL

+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type

+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter

+   

+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL

+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.

+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.

+

+**/  

+EFI_STATUS

+EFIAPI

+GetAttributes(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT UINT64                                           *Attributes

+  );

+  

+/**

+   Sets up the specified PCI root bridge for the bus enumeration process.

+

+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range

+   over which the search should be performed in ACPI 2.0 resource descriptor format.

+

+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.

+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.

+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.

+   

+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle

+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.

+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.

+

+**/

+EFI_STATUS

+EFIAPI

+StartBusEnumeration(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT VOID                                             **Configuration

+  );

+  

+/**

+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.

+

+   This member function programs the specified PCI root bridge to decode the bus range that is

+   specified by the input parameter Configuration.

+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.

+

+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance

+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed

+   @param[in] Configuration     The pointer to the PCI bus resource descriptor

+   

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than 

+                                  bus descriptors.

+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.

+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.

+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+SetBusNumbers(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_HANDLE                                       RootBridgeHandle,

+  IN VOID                                             *Configuration

+  );

+  

+/**

+   Submits the I/O and memory resource requirements for the specified PCI root bridge.

+

+   This function is used to submit all the I/O and memory resources that are required by the specified

+   PCI root bridge. The input parameter Configuration is used to specify the following:

+   - The various types of resources that are required

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.

+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.

+   

+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.

+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.

+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are 

+                                  not supported by this PCI root bridge. This error will happen if the caller 

+                                  did not combine resources according to Attributes that were returned by

+                                  GetAllocAttributes().

+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.

+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.

+

+**/

+EFI_STATUS

+EFIAPI

+SubmitResources(

+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN EFI_HANDLE                                       RootBridgeHandle,

+  IN VOID                                             *Configuration

+  );

+  

+/**

+   Returns the proposed resource settings for the specified PCI root bridge.

+

+   This member function returns the proposed resource settings for the specified PCI root bridge. The

+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of

+   EfiPciHostBridgeAllocateResources. The output parameter Configuration

+   specifies the following:

+   - The various types of resources, excluding bus resources, that are allocated

+   - The associated lengths in terms of ACPI 2.0 resource descriptor format

+

+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.

+   

+   @retval EFI_SUCCESS            The requested parameters were returned.

+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+GetProposedResources(

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,

+  IN  EFI_HANDLE                                       RootBridgeHandle,

+  OUT VOID                                             **Configuration

+  );

+

+/**

+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various

+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual

+   PCI controllers before enumeration.

+

+   This function is called during the PCI enumeration process. No specific action is expected from this

+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before

+   enumeration.

+

+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.

+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in

+                            InstallProtocolInterface() in the UEFI 2.0 Specification.

+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the

+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI

+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for

+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.

+   @param Phase             The phase of the PCI device enumeration. 

+   

+   @retval EFI_SUCCESS              The requested parameters were returned.

+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.

+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in

+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.

+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should

+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI

+                                    bridge.

+

+**/

+EFI_STATUS

+EFIAPI

+PreprocessController (

+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *This,

+  IN  EFI_HANDLE                                        RootBridgeHandle,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       PciAddress,

+  IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase

+  );

+

+

+//

+// Define resource status constant 

+//

+#define EFI_RESOURCE_NONEXISTENT   0xFFFFFFFFFFFFFFFFULL

+#define EFI_RESOURCE_LESS          0xFFFFFFFFFFFFFFFEULL

+

+

+//

+// Driver Instance Data Prototypes

+//

+

+typedef struct {

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation;

+  UINTN                                      NumberOfBytes;

+  UINTN                                      NumberOfPages;

+  EFI_PHYSICAL_ADDRESS                       HostAddress;

+  EFI_PHYSICAL_ADDRESS                       MappedHostAddress;

+} MAP_INFO;

+

+typedef struct {

+  ACPI_HID_DEVICE_PATH              AcpiDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL          EndDevicePath;

+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;

+

+typedef struct {

+  UINT64          BusBase;

+  UINT64          BusLimit;     

+  

+  UINT64          MemBase;     

+  UINT64          MemLimit;    

+  

+  UINT64          IoBase; 

+  UINT64          IoLimit;     

+} PCI_ROOT_BRIDGE_RESOURCE_APPETURE;

+

+typedef enum {

+  TypeIo = 0,

+  TypeMem32,

+  TypePMem32,

+  TypeMem64,

+  TypePMem64,

+  TypeBus,

+  TypeMax

+} PCI_RESOURCE_TYPE;

+

+typedef enum {

+  ResNone = 0,

+  ResSubmitted,

+  ResRequested,

+  ResAllocated,

+  ResStatusMax

+} RES_STATUS;

+

+typedef struct {

+  PCI_RESOURCE_TYPE Type;

+  UINT64            Base;

+  UINT64            Length;

+  UINT64            Alignment;

+  RES_STATUS        Status;

+} PCI_RES_NODE;

+

+#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')

+

+typedef struct {

+  UINT32                 Signature;

+  LIST_ENTRY             Link;

+  EFI_HANDLE             Handle;

+  UINT64                 RootBridgeAttrib;

+  UINT64                 Attributes;

+  UINT64                 Supports;

+  

+  //

+  // Specific for this memory controller: Bus, I/O, Mem

+  //

+  PCI_RES_NODE           ResAllocNode[6];

+  

+  //

+  // Addressing for Memory and I/O and Bus arrange

+  //

+  UINT64                 BusBase;

+  UINT64                 MemBase;     

+  UINT64                 IoBase; 

+  UINT64                 BusLimit;     

+  UINT64                 MemLimit;    

+  UINT64                 IoLimit;     

+

+  UINTN                  PciAddress;

+  UINTN                  PciData;

+  

+  EFI_DEVICE_PATH_PROTOCOL                *DevicePath;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         Io;

+

+} PCI_ROOT_BRIDGE_INSTANCE;

+

+

+//

+// Driver Instance Data Macros

+//

+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \

+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)

+

+

+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \

+  CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)

+

+/**

+

+  Construct the Pci Root Bridge Io protocol

+

+  @param Protocol         Point to protocol instance

+  @param HostBridgeHandle Handle of host bridge

+  @param Attri            Attribute of host bridge

+  @param ResAppeture      ResourceAppeture for host bridge

+

+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.

+

+**/

+EFI_STATUS

+RootBridgeConstructor (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,

+  IN EFI_HANDLE                         HostBridgeHandle,

+  IN UINT64                             Attri,

+  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.uni
new file mode 100644
index 0000000..b87718f
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf
new file mode 100644
index 0000000..613c29f
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -0,0 +1,65 @@
+## @file

+#  The basic interfaces implementation to a single segment PCI Host Bridge driver.

+#

+#  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PciHostBridge

+  MODULE_UNI_FILE                = PciHostBridge.uni

+  FILE_GUID                      = 2383608E-C6D0-4e3e-858D-45DFAC3543D5

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializePciHostBridge

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiDriverEntryPoint

+  UefiBootServicesTableLib

+  DxeServicesTableLib

+  UefiLib

+  MemoryAllocationLib

+  BaseMemoryLib

+  BaseLib

+  DebugLib

+  DevicePathLib

+  IoLib

+  PciLib

+

+[Sources]

+  PciHostBridge.c

+  PciRootBridgeIo.c

+  PciHostBridge.h

+  IoFifo.h

+

+[Sources.IA32]

+  Ia32/IoFifo.asm

+  Ia32/IoFifo.S

+

+[Sources.X64]

+  X64/IoFifo.asm

+  X64/IoFifo.S

+

+[Protocols]

+  gEfiPciHostBridgeResourceAllocationProtocolGuid       ## PRODUCES

+  gEfiPciRootBridgeIoProtocolGuid                       ## PRODUCES

+  gEfiMetronomeArchProtocolGuid                         ## CONSUMES

+  gEfiDevicePathProtocolGuid                            ## PRODUCES

+

+[depex]

+  gEfiMetronomeArchProtocolGuid

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  PciHostBridgeExtra.uni

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeExtra.uni b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeExtra.uni
new file mode 100644
index 0000000..2684980
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridgeExtra.uni
Binary files differ
diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
new file mode 100644
index 0000000..7946324
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -0,0 +1,2171 @@
+/** @file

+  PCI Root Bridge Io Protocol implementation

+

+Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>

+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.

+

+**/ 

+

+#include "PciHostBridge.h"

+#include "IoFifo.h"

+

+typedef struct {

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     SpaceDesp[TypeMax];

+  EFI_ACPI_END_TAG_DESCRIPTOR           EndDesp;

+} RESOURCE_CONFIGURATION;

+

+RESOURCE_CONFIGURATION Configuration = {

+  {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},

+  {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0}, 

+  {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},

+  {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},

+  {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},

+  {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},

+  {0x79, 0}

+};

+

+//

+// Protocol Member Function Prototypes

+//

+

+/**

+   Polls an address in memory mapped I/O space until an exit condition is met, or 

+   a timeout occurs. 

+

+   This function provides a standard way to poll a PCI memory location. A PCI memory read

+   operation is performed at the PCI memory address specified by Address for the width specified

+   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory

+   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &

+   Mask) is equal to Value.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The base address of the memory operations. The caller is

+                          responsible for aligning Address if required.

+   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask

+                          are ignored. The bits in the bytes below Width which are zero in

+                          Mask are ignored when polling the memory address.

+   @param[in]   Value     The comparison value used for the polling exit criteria.

+   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may

+                          be of poorer granularity.

+   @param[out]  Result    Pointer to the last value read from the memory location.

+   

+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.

+   @retval EFI_INVALID_PARAMETER  Width is invalid.

+   @retval EFI_INVALID_PARAMETER  Result is NULL.

+   @retval EFI_TIMEOUT            Delay expired before a match occurred.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollMem ( 

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  );

+  

+/**

+   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is

+   satisfied or after a defined duration.

+

+   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is

+   performed at the PCI I/O address specified by Address for the width specified by Width.

+   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is

+   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal

+   to Value.

+

+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in] Width     Signifies the width of the I/O operations.

+   @param[in] Address   The base address of the I/O operations. The caller is responsible

+                        for aligning Address if required.

+   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask

+                        are ignored. The bits in the bytes below Width which are zero in

+                        Mask are ignored when polling the I/O address.

+   @param[in] Value     The comparison value used for the polling exit criteria.

+   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may

+                        be of poorer granularity.

+   @param[out] Result   Pointer to the last value read from the memory location.

+   

+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.

+   @retval EFI_INVALID_PARAMETER  Width is invalid.

+   @retval EFI_INVALID_PARAMETER  Result is NULL.

+   @retval EFI_TIMEOUT            Delay expired before a match occurred.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollIo ( 

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  );

+  

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.

+

+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller

+   registers in the PCI root bridge memory space.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operation.

+   @param[in]   Address   The base address of the memory operation. The caller is

+                          responsible for aligning the Address if required.

+   @param[in]   Count     The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at Address.

+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  );

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.

+

+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller

+   registers in the PCI root bridge memory space.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operation.

+   @param[in]   Address   The base address of the memory operation. The caller is

+                          responsible for aligning the Address if required.

+   @param[in]   Count     The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at Address.

+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  );

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width       Signifies the width of the memory operations.

+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for

+                            aligning the Address if required.

+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width

+                            size * Count, starting at Address.

+   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For

+                            write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 UserAddress,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *UserBuffer

+  );

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width       Signifies the width of the memory operations.

+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for

+                            aligning the Address if required.

+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width

+                            size * Count, starting at Address.

+   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For

+                            write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 UserAddress,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *UserBuffer

+  );

+

+/**

+   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI

+   root bridge memory space.

+

+   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory

+   space to another region of PCI root bridge memory space. This is especially useful for video scroll

+   operation on a memory mapped video buffer.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI root bridge on a platform might require.

+

+   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.

+   @param[in] Width       Signifies the width of the memory operations.

+   @param[in] DestAddress The destination address of the memory operation. The caller is

+                          responsible for aligning the DestAddress if required.

+   @param[in] SrcAddress  The source address of the memory operation. The caller is

+                          responsible for aligning the SrcAddress if required.

+   @param[in] Count       The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at DestAddress and SrcAddress.

+   

+   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.

+   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.

+   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoCopyMem (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 DestAddress,

+  IN     UINT64                                 SrcAddress,

+  IN     UINTN                                  Count

+  );

+

+/**

+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.

+

+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration

+   registers for a PCI controller.

+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for

+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might

+   require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes

+                          moved is Width size * Count, starting at Address.

+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  );

+

+/**

+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.

+

+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration

+   registers for a PCI controller.

+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for

+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might

+   require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes

+                          moved is Width size * Count, starting at Address.

+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  );

+

+/**

+   Provides the PCI controller-specific addresses required to access system memory from a

+   DMA bus master.

+

+   The Map() function provides the PCI controller specific addresses needed to access system

+   memory. This function is used to map system memory for PCI bus master DMA accesses.

+

+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.

+   @param[in]       HostAddress     The system memory address to map to the PCI controller.

+   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.

+   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use

+                                    to access the system memory's HostAddress.

+   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.

+   

+   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.

+   @retval EFI_INVALID_PARAMETER  Operation is invalid.

+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.

+   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.

+   @retval EFI_INVALID_PARAMETER  Mapping is NULL.

+   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.

+   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMap (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                                       *HostAddress,

+  IN OUT UINTN                                      *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,

+  OUT    VOID                                       **Mapping

+  );

+

+/**

+   Completes the Map() operation and releases any corresponding resources.

+

+   The Unmap() function completes the Map() operation and releases any corresponding resources.

+   If the operation was an EfiPciOperationBusMasterWrite or

+   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.

+   Any resources used for the mapping are freed.  

+

+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in] Mapping   The mapping value returned from Map().

+   

+   @retval EFI_SUCCESS            The range was unmapped.

+   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().

+   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoUnmap (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  VOID                             *Mapping

+  );

+

+/**

+   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or

+   EfiPciOperationBusMasterCommonBuffer64 mapping.

+  

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Type        This parameter is not used and must be ignored.

+   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.

+   @param Pages       The number of pages to allocate.

+   @param HostAddress A pointer to store the base system memory address of the allocated range.

+   @param Attributes  The requested bit mask of attributes for the allocated range. Only

+                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, 

+                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.

+   

+   @retval EFI_SUCCESS            The requested memory pages were allocated.

+   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.

+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are

+                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.

+   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoAllocateBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  EFI_ALLOCATE_TYPE                Type,

+  IN  EFI_MEMORY_TYPE                  MemoryType,

+  IN  UINTN                            Pages,

+  OUT VOID                             **HostAddress,

+  IN  UINT64                           Attributes

+  );

+

+/**

+   Frees memory that was allocated with AllocateBuffer().

+

+   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Pages       The number of pages to free.

+   @param HostAddress The base system memory address of the allocated range.

+   

+   @retval EFI_SUCCESS            The requested memory pages were freed.

+   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages

+                                  was not allocated with AllocateBuffer().

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFreeBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  UINTN                            Pages,

+  OUT VOID                             *HostAddress

+  );

+

+/**

+   Flushes all PCI posted write transactions from a PCI host bridge to system memory.

+

+   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system

+   memory. Posted write transactions are generated by PCI bus masters when they perform write

+   transactions to target addresses in system memory.

+   This function does not flush posted write transactions from any PCI bridges. A PCI controller

+   specific action must be taken to guarantee that the posted write transactions have been flushed from

+   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with

+   a PCI read transaction from the PCI controller prior to calling Flush().

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   

+   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host

+                              bridge to system memory.

+   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI

+                              host bridge due to a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFlush (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This

+  );

+

+/**

+   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the

+   attributes that a PCI root bridge is currently using.  

+

+   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports

+   and the mask of attributes that the PCI root bridge is currently using.

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Supported   A pointer to the mask of attributes that this PCI root bridge

+                      supports setting with SetAttributes().

+   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is

+                      currently using.

+   

+   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root

+                                  bridge supports is returned in Supports. If Attributes is

+                                  not NULL, then the attributes that the PCI root bridge is currently

+                                  using is returned in Attributes.

+   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoGetAttributes (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT UINT64                           *Supported,

+  OUT UINT64                           *Attributes

+  );

+

+/**

+   Sets attributes for a resource range on a PCI root bridge.

+

+   The SetAttributes() function sets the attributes specified in Attributes for the PCI root

+   bridge on the resource range specified by ResourceBase and ResourceLength. Since the

+   granularity of setting these attributes may vary from resource type to resource type, and from

+   platform to platform, the actual resource range and the one passed in by the caller may differ. As a

+   result, this function may set the attributes specified by Attributes on a larger resource range

+   than the caller requested. The actual range is returned in ResourceBase and

+   ResourceLength. The caller is responsible for verifying that the actual range for which the

+   attributes were set is acceptable.

+

+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]       Attributes      The mask of attributes to set. If the attribute bit

+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or

+                                    MEMORY_DISABLE is set, then the resource range is specified by

+                                    ResourceBase and ResourceLength. If

+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and

+                                    MEMORY_DISABLE are not set, then ResourceBase and

+                                    ResourceLength are ignored, and may be NULL.

+   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified

+                                    by the attributes specified by Attributes.

+   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the

+                                    attributes specified by Attributes.

+   

+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.

+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.

+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoSetAttributes (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN     UINT64                           Attributes,

+  IN OUT UINT64                           *ResourceBase,

+  IN OUT UINT64                           *ResourceLength 

+  ); 

+

+/**

+   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0

+   resource descriptors.

+

+   There are only two resource descriptor types from the ACPI Specification that may be used to

+   describe the current resources allocated to a PCI root bridge. These are the QWORD Address

+   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The

+   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic

+   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD

+   Address Space Descriptors followed by an End Tag.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the

+                            current configuration of this PCI root bridge. The storage for the

+                            ACPI 2.0 resource descriptors is allocated by this function. The

+                            caller must treat the return buffer as read-only data, and the buffer

+                            must not be freed by the caller.

+   

+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.

+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.

+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoConfiguration (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT    VOID                             **Resources

+  );

+

+//

+// Memory Controller Pci Root Bridge Io Module Variables

+//

+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;

+

+//

+// Lookup table for increment values based on transfer widths

+//

+UINT8 mInStride[] = {

+  1, // EfiPciWidthUint8

+  2, // EfiPciWidthUint16

+  4, // EfiPciWidthUint32

+  8, // EfiPciWidthUint64

+  0, // EfiPciWidthFifoUint8

+  0, // EfiPciWidthFifoUint16

+  0, // EfiPciWidthFifoUint32

+  0, // EfiPciWidthFifoUint64

+  1, // EfiPciWidthFillUint8

+  2, // EfiPciWidthFillUint16

+  4, // EfiPciWidthFillUint32

+  8  // EfiPciWidthFillUint64

+};

+

+//

+// Lookup table for increment values based on transfer widths

+//

+UINT8 mOutStride[] = {

+  1, // EfiPciWidthUint8

+  2, // EfiPciWidthUint16

+  4, // EfiPciWidthUint32

+  8, // EfiPciWidthUint64

+  1, // EfiPciWidthFifoUint8

+  2, // EfiPciWidthFifoUint16

+  4, // EfiPciWidthFifoUint32

+  8, // EfiPciWidthFifoUint64

+  0, // EfiPciWidthFillUint8

+  0, // EfiPciWidthFillUint16

+  0, // EfiPciWidthFillUint32

+  0  // EfiPciWidthFillUint64

+};

+

+/**

+

+  Construct the Pci Root Bridge Io protocol

+

+  @param Protocol         Point to protocol instance

+  @param HostBridgeHandle Handle of host bridge

+  @param Attri            Attribute of host bridge

+  @param ResAppeture      ResourceAppeture for host bridge

+

+  @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.

+

+**/

+EFI_STATUS

+RootBridgeConstructor (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *Protocol,

+  IN EFI_HANDLE                         HostBridgeHandle,

+  IN UINT64                             Attri,

+  IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE  *ResAppeture

+  )

+{

+  EFI_STATUS                        Status;

+  PCI_ROOT_BRIDGE_INSTANCE          *PrivateData;

+  PCI_RESOURCE_TYPE                 Index;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);

+

+  //

+  // The host to pci bridge, the host memory and io addresses are

+  // direct mapped to pci addresses, so no need translate, set bases to 0.

+  //

+  PrivateData->MemBase = ResAppeture->MemBase;

+  PrivateData->IoBase  = ResAppeture->IoBase;

+

+  //

+  // The host bridge only supports 32bit addressing for memory

+  // and standard IA32 16bit io

+  //

+  PrivateData->MemLimit = ResAppeture->MemLimit;

+  PrivateData->IoLimit  = ResAppeture->IoLimit;

+

+  //

+  // Bus Appeture for this Root Bridge (Possible Range)

+  //

+  PrivateData->BusBase  = ResAppeture->BusBase;

+  PrivateData->BusLimit = ResAppeture->BusLimit;

+  

+  //

+  // Specific for this chipset

+  //

+  for (Index = TypeIo; Index < TypeMax; Index++) {

+    PrivateData->ResAllocNode[Index].Type      = Index;

+    PrivateData->ResAllocNode[Index].Base      = 0;

+    PrivateData->ResAllocNode[Index].Length    = 0;

+    PrivateData->ResAllocNode[Index].Status    = ResNone;

+  }

+  

+  PrivateData->PciAddress = 0xCF8;

+  PrivateData->PciData    = 0xCFC;

+

+  PrivateData->RootBridgeAttrib = Attri;

+  

+  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \

+                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \

+                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \

+                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;

+  PrivateData->Attributes  = PrivateData->Supports;

+

+  Protocol->ParentHandle   = HostBridgeHandle;

+  

+  Protocol->PollMem        = RootBridgeIoPollMem;

+  Protocol->PollIo         = RootBridgeIoPollIo;

+

+  Protocol->Mem.Read       = RootBridgeIoMemRead;

+  Protocol->Mem.Write      = RootBridgeIoMemWrite;

+

+  Protocol->Io.Read        = RootBridgeIoIoRead;

+  Protocol->Io.Write       = RootBridgeIoIoWrite;

+

+  Protocol->CopyMem        = RootBridgeIoCopyMem;

+

+  Protocol->Pci.Read       = RootBridgeIoPciRead;

+  Protocol->Pci.Write      = RootBridgeIoPciWrite;

+

+  Protocol->Map            = RootBridgeIoMap;

+  Protocol->Unmap          = RootBridgeIoUnmap;

+

+  Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;

+  Protocol->FreeBuffer     = RootBridgeIoFreeBuffer;

+

+  Protocol->Flush          = RootBridgeIoFlush;

+

+  Protocol->GetAttributes  = RootBridgeIoGetAttributes;

+  Protocol->SetAttributes  = RootBridgeIoSetAttributes;

+

+  Protocol->Configuration  = RootBridgeIoConfiguration;

+

+  Protocol->SegmentNumber  = 0;

+

+  Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.

+

+  The I/O operations are carried out exactly as requested. The caller is responsible 

+  for satisfying any alignment and I/O width restrictions that a PI System on a 

+  platform might require. For example on some platforms, width requests of 

+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will 

+  be handled by the driver.

+  

+  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.

+  @param[in] Width          Signifies the width of the I/O or Memory operation.

+  @param[in] Address        The base address of the I/O operation. 

+  @param[in] Count          The number of I/O operations to perform. The number of  

+                            bytes moved is Width size * Count, starting at Address.

+  @param[in] Buffer         For read operations, the destination buffer to store the results.

+                            For write operations, the source buffer from which to write data.

+

+  @retval EFI_SUCCESS            The parameters for this request pass the checks.

+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.

+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.

+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width, 

+                                 and Count is not valid for this PI system.

+

+**/

+EFI_STATUS

+RootBridgeIoCheckParameter (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN OPERATION_TYPE                         OperationType,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN UINT64                                 Address,

+  IN UINTN                                  Count,

+  IN VOID                                   *Buffer

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;

+  UINT64                                       MaxCount;

+  UINT64                                       Base;

+  UINT64                                       Limit;

+

+  //

+  // Check to see if Buffer is NULL

+  //

+  if (Buffer == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check to see if Width is in the valid range

+  //

+  if ((UINT32)Width >= EfiPciWidthMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // For FIFO type, the target address won't increase during the access,

+  // so treat Count as 1

+  //

+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {

+    Count = 1;

+  }

+

+  //

+  // Check to see if Width is in the valid range for I/O Port operations

+  //

+  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);

+  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {

+    ASSERT (FALSE);

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Check to see if Address is aligned

+  //

+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+

+  //

+  // Check to see if any address associated with this transfer exceeds the maximum 

+  // allowed address.  The maximum address implied by the parameters passed in is

+  // Address + Size * Count.  If the following condition is met, then the transfer

+  // is not supported.

+  //

+  //    Address + Size * Count > Limit + 1

+  //

+  // Since Limit can be the maximum integer value supported by the CPU and Count 

+  // can also be the maximum integer value supported by the CPU, this range

+  // check must be adjusted to avoid all oveflow conditions.

+  //   

+  // The following form of the range check is equivalent but assumes that 

+  // Limit is of the form (2^n - 1).

+  //

+  if (OperationType == IoOperation) {

+    Base = PrivateData->IoBase;

+    Limit = PrivateData->IoLimit;

+  } else if (OperationType == MemOperation) {

+    Base = PrivateData->MemBase;

+    Limit = PrivateData->MemLimit;

+  } else {

+    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;

+    if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (PciRbAddr->ExtendedRegister != 0) {

+      Address = PciRbAddr->ExtendedRegister;

+    } else {

+      Address = PciRbAddr->Register;

+    }

+    Base = 0;

+    Limit = MAX_PCI_REG_ADDRESS;

+  }

+

+  if (Address < Base) {

+      return EFI_INVALID_PARAMETER;

+  }

+

+  if (Count == 0) {

+    if (Address > Limit) {

+      return EFI_UNSUPPORTED;

+    }

+  } else {  

+    MaxCount = RShiftU64 (Limit, Width);

+    if (MaxCount < (Count - 1)) {

+      return EFI_UNSUPPORTED;

+    }

+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+   Internal help function for read and write memory space.

+

+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Write         Switch value for Read or Write.

+   @param[in]   Width         Signifies the width of the memory operations.

+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes

+                              moved is Width size * Count, starting at Address.

+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For

+                              write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+RootBridgeIoMemRW (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     BOOLEAN                                Write,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN OUT VOID                                   *Buffer

+  )

+{

+  EFI_STATUS                             Status;

+  UINT8                                  InStride;

+  UINT8                                  OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;

+  UINT8                                  *Uint8Buffer;

+

+  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  InStride = mInStride[Width];

+  OutStride = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);

+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          MmioWrite8 ((UINTN)Address, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint64:

+          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = MmioRead8 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint64:

+          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+  return EFI_SUCCESS;  

+}

+

+/**

+   Internal help function for read and write IO space.

+

+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Write         Switch value for Read or Write.

+   @param[in]   Width         Signifies the width of the memory operations.

+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes

+                              moved is Width size * Count, starting at Address.

+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For

+                              write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+RootBridgeIoIoRW (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     BOOLEAN                                Write,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN OUT VOID                                   *Buffer

+  )

+{

+  EFI_STATUS                             Status;

+  UINT8                                  InStride;

+  UINT8                                  OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;

+  UINT8                                  *Uint8Buffer;

+

+  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  InStride = mInStride[Width];

+  OutStride = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);

+

+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)

+  if (InStride == 0) {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoWriteFifo8 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint16:

+          IoWriteFifo16 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint32:

+          IoWriteFifo32 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoReadFifo8 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint16:

+          IoReadFifo16 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        case EfiPciWidthUint32:

+          IoReadFifo32 ((UINTN) Address, Count, Buffer);

+          return EFI_SUCCESS;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+#endif

+

+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          IoWrite8 ((UINTN)Address, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = IoRead8 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+   Internal help function for read and write PCI configuration space.

+

+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Write         Switch value for Read or Write.

+   @param[in]   Width         Signifies the width of the memory operations.

+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes

+                              moved is Width size * Count, starting at Address.

+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For

+                              write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+RootBridgeIoPciRW (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN BOOLEAN                                Write,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN UINT64                                 Address,

+  IN UINTN                                  Count,

+  IN OUT VOID                               *Buffer

+  )

+{

+  EFI_STATUS                                   Status;

+  UINT8                                        InStride;

+  UINT8                                        OutStride;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        OperationWidth;

+  UINT8                                        *Uint8Buffer;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;

+  UINTN                                        PcieRegAddr;

+

+  Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;

+

+  PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (

+                          PciRbAddr->Bus,

+                          PciRbAddr->Device,

+                          PciRbAddr->Function,

+                          (PciRbAddr->ExtendedRegister != 0) ? \

+                            PciRbAddr->ExtendedRegister :

+                            PciRbAddr->Register

+                          );

+

+  InStride = mInStride[Width];

+  OutStride = mOutStride[Width];

+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);

+  for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {

+    if (Write) {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          PciWrite8 (PcieRegAddr, *Uint8Buffer);

+          break;

+        case EfiPciWidthUint16:

+          PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));

+          break;

+        case EfiPciWidthUint32:

+          PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    } else {

+      switch (OperationWidth) {

+        case EfiPciWidthUint8:

+          *Uint8Buffer = PciRead8 (PcieRegAddr);

+          break;

+        case EfiPciWidthUint16:

+          *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);

+          break;

+        case EfiPciWidthUint32:

+          *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);

+          break;

+        default:

+          //

+          // The RootBridgeIoCheckParameter call above will ensure that this

+          // path is not taken.

+          //

+          ASSERT (FALSE);

+          break;

+      }

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+   Polls an address in memory mapped I/O space until an exit condition is met, or 

+   a timeout occurs. 

+

+   This function provides a standard way to poll a PCI memory location. A PCI memory read

+   operation is performed at the PCI memory address specified by Address for the width specified

+   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory

+   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &

+   Mask) is equal to Value.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The base address of the memory operations. The caller is

+                          responsible for aligning Address if required.

+   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask

+                          are ignored. The bits in the bytes below Width which are zero in

+                          Mask are ignored when polling the memory address.

+   @param[in]   Value     The comparison value used for the polling exit criteria.

+   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may

+                          be of poorer granularity.

+   @param[out]  Result    Pointer to the last value read from the memory location.

+   

+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.

+   @retval EFI_INVALID_PARAMETER  Width is invalid.

+   @retval EFI_INVALID_PARAMETER  Result is NULL.

+   @retval EFI_TIMEOUT            Delay expired before a match occurred.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollMem ( 

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      NumberOfTicks;

+  UINT32      Remainder;

+

+  if (Result == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // No matter what, always do a single poll.

+  //

+  Status = This->Mem.Read (This, Width, Address, 1, Result);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }    

+  if ((*Result & Mask) == Value) {

+    return EFI_SUCCESS;

+  }

+

+  if (Delay == 0) {

+    return EFI_SUCCESS;

+  

+  } else {

+

+    //

+    // Determine the proper # of metronome ticks to wait for polling the

+    // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1

+    // The "+1" to account for the possibility of the first tick being short

+    // because we started in the middle of a tick.

+    //

+    // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome

+    // protocol definition is updated.

+    //

+    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);

+    if (Remainder != 0) {

+      NumberOfTicks += 1;

+    }

+    NumberOfTicks += 1;

+  

+    while (NumberOfTicks != 0) {

+

+      mMetronome->WaitForTick (mMetronome, 1);

+    

+      Status = This->Mem.Read (This, Width, Address, 1, Result);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    

+      if ((*Result & Mask) == Value) {

+        return EFI_SUCCESS;

+      }

+

+      NumberOfTicks -= 1;

+    }

+  }

+  return EFI_TIMEOUT;

+}

+  

+/**

+   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is

+   satisfied or after a defined duration.

+

+   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is

+   performed at the PCI I/O address specified by Address for the width specified by Width.

+   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is

+   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal

+   to Value.

+

+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in] Width     Signifies the width of the I/O operations.

+   @param[in] Address   The base address of the I/O operations. The caller is responsible

+                        for aligning Address if required.

+   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask

+                        are ignored. The bits in the bytes below Width which are zero in

+                        Mask are ignored when polling the I/O address.

+   @param[in] Value     The comparison value used for the polling exit criteria.

+   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may

+                        be of poorer granularity.

+   @param[out] Result   Pointer to the last value read from the memory location.

+   

+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.

+   @retval EFI_INVALID_PARAMETER  Width is invalid.

+   @retval EFI_INVALID_PARAMETER  Result is NULL.

+   @retval EFI_TIMEOUT            Delay expired before a match occurred.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPollIo ( 

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT64                                 Address,

+  IN  UINT64                                 Mask,

+  IN  UINT64                                 Value,

+  IN  UINT64                                 Delay,

+  OUT UINT64                                 *Result

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      NumberOfTicks;

+  UINT32      Remainder;

+

+  //

+  // No matter what, always do a single poll.

+  //

+

+  if (Result == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  Status = This->Io.Read (This, Width, Address, 1, Result);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }    

+  if ((*Result & Mask) == Value) {

+    return EFI_SUCCESS;

+  }

+

+  if (Delay == 0) {

+    return EFI_SUCCESS;

+  

+  } else {

+

+    //

+    // Determine the proper # of metronome ticks to wait for polling the

+    // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1

+    // The "+1" to account for the possibility of the first tick being short

+    // because we started in the middle of a tick.

+    //

+    NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);

+    if (Remainder != 0) {

+      NumberOfTicks += 1;

+    }

+    NumberOfTicks += 1;

+  

+    while (NumberOfTicks != 0) {

+

+      mMetronome->WaitForTick (mMetronome, 1);

+    

+      Status = This->Io.Read (This, Width, Address, 1, Result);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+    

+      if ((*Result & Mask) == Value) {

+        return EFI_SUCCESS;

+      }

+

+      NumberOfTicks -= 1;

+    }

+  }

+  return EFI_TIMEOUT;

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.

+

+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller

+   registers in the PCI root bridge memory space.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operation.

+   @param[in]   Address   The base address of the memory operation. The caller is

+                          responsible for aligning the Address if required.

+   @param[in]   Count     The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at Address.

+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.

+

+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller

+   registers in the PCI root bridge memory space.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operation.

+   @param[in]   Address   The base address of the memory operation. The caller is

+                          responsible for aligning the Address if required.

+   @param[in]   Count     The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at Address.

+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMemWrite (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  IN     VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);  

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width       Signifies the width of the memory operations.

+   @param[in]   Address     The base address of the I/O operation. The caller is responsible for

+                            aligning the Address if required.

+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width

+                            size * Count, starting at Address.

+   @param[out]  Buffer      For read operations, the destination buffer to store the results. For

+                            write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoRead (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN     UINT64                                 Address,

+  IN     UINTN                                  Count,

+  OUT    VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);  

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width       Signifies the width of the memory operations.

+   @param[in]   Address     The base address of the I/O operation. The caller is responsible for

+                            aligning the Address if required.

+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width

+                            size * Count, starting at Address.

+   @param[in]   Buffer       For read operations, the destination buffer to store the results. For

+                            write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoIoWrite (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,

+  IN       UINT64                                  Address,

+  IN       UINTN                                   Count,

+  IN       VOID                                    *Buffer

+  )

+{

+  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);  

+}

+

+/**

+   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI

+   root bridge memory space.

+

+   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory

+   space to another region of PCI root bridge memory space. This is especially useful for video scroll

+   operation on a memory mapped video buffer.

+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying

+   any alignment and memory width restrictions that a PCI root bridge on a platform might require.

+

+   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.

+   @param[in] Width       Signifies the width of the memory operations.

+   @param[in] DestAddress The destination address of the memory operation. The caller is

+                          responsible for aligning the DestAddress if required.

+   @param[in] SrcAddress  The source address of the memory operation. The caller is

+                          responsible for aligning the SrcAddress if required.

+   @param[in] Count       The number of memory operations to perform. Bytes moved is

+                          Width size * Count, starting at DestAddress and SrcAddress.

+   

+   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.

+   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.

+   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoCopyMem (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,

+  IN UINT64                                       DestAddress,

+  IN UINT64                                       SrcAddress,

+  IN UINTN                                        Count

+  )

+{

+  EFI_STATUS  Status;

+  BOOLEAN     Direction;

+  UINTN       Stride;

+  UINTN       Index;

+  UINT64      Result;

+

+  if ((UINT32)Width > EfiPciWidthUint64) {

+    return EFI_INVALID_PARAMETER;

+  }    

+

+  if (DestAddress == SrcAddress) {

+    return EFI_SUCCESS;

+  }

+

+  Stride = (UINTN)(1 << Width);

+

+  Direction = TRUE;

+  if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {

+    Direction   = FALSE;

+    SrcAddress  = SrcAddress  + (Count-1) * Stride;

+    DestAddress = DestAddress + (Count-1) * Stride;

+  }

+

+  for (Index = 0;Index < Count;Index++) {

+    Status = RootBridgeIoMemRead (

+               This,

+               Width,

+               SrcAddress,

+               1,

+               &Result

+               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    Status = RootBridgeIoMemWrite (

+               This,

+               Width,

+               DestAddress,

+               1,

+               &Result

+               );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    if (Direction) {

+      SrcAddress  += Stride;

+      DestAddress += Stride;

+    } else {

+      SrcAddress  -= Stride;

+      DestAddress -= Stride;

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.

+

+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration

+   registers for a PCI controller.

+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for

+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might

+   require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes

+                          moved is Width size * Count, starting at Address.

+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciRead (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN       UINT64                                 Address,

+  IN       UINTN                                  Count,

+  OUT      VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);

+}

+

+/**

+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.

+

+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration

+   registers for a PCI controller.

+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for

+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might

+   require.

+

+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]   Width     Signifies the width of the memory operations.

+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.

+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes

+                          moved is Width size * Count, starting at Address.

+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For

+                          write operations, the source buffer to write data from.

+   

+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.

+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoPciWrite (

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,

+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN       UINT64                                 Address,

+  IN       UINTN                                  Count,

+  IN       VOID                                   *Buffer

+  )

+{

+  return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);

+}

+

+/**

+   Provides the PCI controller-specific addresses required to access system memory from a

+   DMA bus master.

+

+   The Map() function provides the PCI controller specific addresses needed to access system

+   memory. This function is used to map system memory for PCI bus master DMA accesses.

+

+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.

+   @param[in]       HostAddress     The system memory address to map to the PCI controller.

+   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.

+   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use

+                                    to access the system memory's HostAddress.

+   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.

+   

+   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.

+   @retval EFI_INVALID_PARAMETER  Operation is invalid.

+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.

+   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.

+   @retval EFI_INVALID_PARAMETER  Mapping is NULL.

+   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.

+   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.

+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoMap (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL            *This,

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  Operation,

+  IN     VOID                                       *HostAddress,

+  IN OUT UINTN                                      *NumberOfBytes,

+  OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,

+  OUT    VOID                                       **Mapping

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;

+  MAP_INFO              *MapInfo;

+

+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  //

+  // Initialize the return values to their defaults

+  //

+  *Mapping = NULL;

+

+  //

+  // Make sure that Operation is valid

+  //

+  if ((UINT32)Operation >= EfiPciOperationMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Most PCAT like chipsets can not handle performing DMA above 4GB.

+  // If any part of the DMA transfer being mapped is above 4GB, then

+  // map the DMA transfer to a buffer below 4GB.

+  //

+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;

+  if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {

+

+    //

+    // Common Buffer operations can not be remapped.  If the common buffer

+    // if above 4GB, then it is not possible to generate a mapping, so return 

+    // an error.

+    //

+    if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {

+      return EFI_UNSUPPORTED;

+    }

+

+    //

+    // Allocate a MAP_INFO structure to remember the mapping when Unmap() is

+    // called later.

+    //

+    Status = gBS->AllocatePool (

+                    EfiBootServicesData, 

+                    sizeof(MAP_INFO), 

+                    (VOID **)&MapInfo

+                    );

+    if (EFI_ERROR (Status)) {

+      *NumberOfBytes = 0;

+      return Status;

+    }

+

+    //

+    // Return a pointer to the MAP_INFO structure in Mapping

+    //

+    *Mapping = MapInfo;

+

+    //

+    // Initialize the MAP_INFO structure

+    //

+    MapInfo->Operation         = Operation;

+    MapInfo->NumberOfBytes     = *NumberOfBytes;

+    MapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES(*NumberOfBytes);

+    MapInfo->HostAddress       = PhysicalAddress;

+    MapInfo->MappedHostAddress = 0x00000000ffffffff;

+

+    //

+    // Allocate a buffer below 4GB to map the transfer to.

+    //

+    Status = gBS->AllocatePages (

+                    AllocateMaxAddress, 

+                    EfiBootServicesData, 

+                    MapInfo->NumberOfPages,

+                    &MapInfo->MappedHostAddress

+                    );

+    if (EFI_ERROR (Status)) {

+      gBS->FreePool (MapInfo);

+      *NumberOfBytes = 0;

+      return Status;

+    }

+

+    //

+    // If this is a read operation from the Bus Master's point of view,

+    // then copy the contents of the real buffer into the mapped buffer

+    // so the Bus Master can read the contents of the real buffer.

+    //

+    if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {

+      CopyMem (

+        (VOID *)(UINTN)MapInfo->MappedHostAddress, 

+        (VOID *)(UINTN)MapInfo->HostAddress,

+        MapInfo->NumberOfBytes

+        );

+    }

+

+    //

+    // The DeviceAddress is the address of the maped buffer below 4GB

+    //

+    *DeviceAddress = MapInfo->MappedHostAddress;

+  } else {

+    //

+    // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress

+    //

+    *DeviceAddress = PhysicalAddress;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+   Completes the Map() operation and releases any corresponding resources.

+

+   The Unmap() function completes the Map() operation and releases any corresponding resources.

+   If the operation was an EfiPciOperationBusMasterWrite or

+   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.

+   Any resources used for the mapping are freed.  

+

+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in] Mapping   The mapping value returned from Map().

+   

+   @retval EFI_SUCCESS            The range was unmapped.

+   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().

+   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoUnmap (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN VOID                             *Mapping

+  )

+{

+  MAP_INFO    *MapInfo;

+

+  //

+  // See if the Map() operation associated with this Unmap() required a mapping buffer.

+  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.

+  //

+  if (Mapping != NULL) {

+    //

+    // Get the MAP_INFO structure from Mapping

+    //

+    MapInfo = (MAP_INFO *)Mapping;

+

+    //

+    // If this is a write operation from the Bus Master's point of view,

+    // then copy the contents of the mapped buffer into the real buffer

+    // so the processor can read the contents of the real buffer.

+    //

+    if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {

+      CopyMem (

+        (VOID *)(UINTN)MapInfo->HostAddress, 

+        (VOID *)(UINTN)MapInfo->MappedHostAddress,

+        MapInfo->NumberOfBytes

+        );

+    }

+

+    //

+    // Free the mapped buffer and the MAP_INFO structure.

+    //

+    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);

+    gBS->FreePool (Mapping);

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or

+   EfiPciOperationBusMasterCommonBuffer64 mapping.

+  

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Type        This parameter is not used and must be ignored.

+   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.

+   @param Pages       The number of pages to allocate.

+   @param HostAddress A pointer to store the base system memory address of the allocated range.

+   @param Attributes  The requested bit mask of attributes for the allocated range. Only

+                      the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, 

+                      and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.

+   

+   @retval EFI_SUCCESS            The requested memory pages were allocated.

+   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.

+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.

+   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are

+                                  MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.

+   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoAllocateBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  EFI_ALLOCATE_TYPE                Type,

+  IN  EFI_MEMORY_TYPE                  MemoryType,

+  IN  UINTN                            Pages,

+  OUT VOID                             **HostAddress,

+  IN  UINT64                           Attributes

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;

+

+  //

+  // Validate Attributes

+  //

+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Check for invalid inputs

+  //

+  if (HostAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+ 

+  //

+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData

+  //

+  if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Limit allocations to memory below 4GB

+  //

+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);

+

+  Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  *HostAddress = (VOID *)(UINTN)PhysicalAddress;

+

+  return EFI_SUCCESS;

+}

+

+/**

+   Frees memory that was allocated with AllocateBuffer().

+

+   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Pages       The number of pages to free.

+   @param HostAddress The base system memory address of the allocated range.

+   

+   @retval EFI_SUCCESS            The requested memory pages were freed.

+   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages

+                                  was not allocated with AllocateBuffer().

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFreeBuffer (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN  UINTN                            Pages,

+  OUT VOID                             *HostAddress

+  )

+{

+  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);

+}

+

+/**

+   Flushes all PCI posted write transactions from a PCI host bridge to system memory.

+

+   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system

+   memory. Posted write transactions are generated by PCI bus masters when they perform write

+   transactions to target addresses in system memory.

+   This function does not flush posted write transactions from any PCI bridges. A PCI controller

+   specific action must be taken to guarantee that the posted write transactions have been flushed from

+   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with

+   a PCI read transaction from the PCI controller prior to calling Flush().

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   

+   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host

+                              bridge to system memory.

+   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI

+                              host bridge due to a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoFlush (

+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This

+  )

+{

+  //

+  // not supported yet

+  //

+  return EFI_SUCCESS;

+}

+

+/**

+   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the

+   attributes that a PCI root bridge is currently using.  

+

+   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports

+   and the mask of attributes that the PCI root bridge is currently using.

+

+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param Supported   A pointer to the mask of attributes that this PCI root bridge

+                      supports setting with SetAttributes().

+   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is

+                      currently using.

+   

+   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root

+                                  bridge supports is returned in Supports. If Attributes is

+                                  not NULL, then the attributes that the PCI root bridge is currently

+                                  using is returned in Attributes.

+   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoGetAttributes (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  OUT UINT64                           *Supported,

+  OUT UINT64                           *Attributes

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE *PrivateData;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);

+

+  if (Attributes == NULL && Supported == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Set the return value for Supported and Attributes

+  //

+  if (Supported != NULL) {

+    *Supported  = PrivateData->Supports; 

+  }

+

+  if (Attributes != NULL) {

+    *Attributes = PrivateData->Attributes;

+  }

+  

+  return EFI_SUCCESS;

+}

+

+/**

+   Sets attributes for a resource range on a PCI root bridge.

+

+   The SetAttributes() function sets the attributes specified in Attributes for the PCI root

+   bridge on the resource range specified by ResourceBase and ResourceLength. Since the

+   granularity of setting these attributes may vary from resource type to resource type, and from

+   platform to platform, the actual resource range and the one passed in by the caller may differ. As a

+   result, this function may set the attributes specified by Attributes on a larger resource range

+   than the caller requested. The actual range is returned in ResourceBase and

+   ResourceLength. The caller is responsible for verifying that the actual range for which the

+   attributes were set is acceptable.

+

+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[in]       Attributes      The mask of attributes to set. If the attribute bit

+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, or

+                                    MEMORY_DISABLE is set, then the resource range is specified by

+                                    ResourceBase and ResourceLength. If

+                                    MEMORY_WRITE_COMBINE, MEMORY_CACHED, and

+                                    MEMORY_DISABLE are not set, then ResourceBase and

+                                    ResourceLength are ignored, and may be NULL.

+   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified

+                                    by the attributes specified by Attributes.

+   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the

+                                    attributes specified by Attributes.

+   

+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.

+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.

+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoSetAttributes (

+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *This,

+  IN     UINT64                           Attributes,

+  IN OUT UINT64                           *ResourceBase,

+  IN OUT UINT64                           *ResourceLength 

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE            *PrivateData;

+  

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);

+  

+  if (Attributes != 0) {

+    if ((Attributes & (~(PrivateData->Supports))) != 0) {

+      return EFI_UNSUPPORTED;

+    }

+  }

+  

+  //

+  // This is a generic driver for a PC-AT class system.  It does not have any

+  // chipset specific knowlegde, so none of the attributes can be set or 

+  // cleared.  Any attempt to set attribute that are already set will succeed, 

+  // and any attempt to set an attribute that is not supported will fail.

+  //

+  if (Attributes & (~PrivateData->Attributes)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0

+   resource descriptors.

+

+   There are only two resource descriptor types from the ACPI Specification that may be used to

+   describe the current resources allocated to a PCI root bridge. These are the QWORD Address

+   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The

+   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic

+   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD

+   Address Space Descriptors followed by an End Tag.

+

+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

+   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the

+                            current configuration of this PCI root bridge. The storage for the

+                            ACPI 2.0 resource descriptors is allocated by this function. The

+                            caller must treat the return buffer as read-only data, and the buffer

+                            must not be freed by the caller.

+   

+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.

+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.

+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

+

+**/

+EFI_STATUS

+EFIAPI

+RootBridgeIoConfiguration (

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *This,

+  OUT VOID                                **Resources

+  )

+{

+  PCI_ROOT_BRIDGE_INSTANCE              *PrivateData;

+  UINTN                                 Index;

+

+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);

+  

+  for (Index = 0; Index < TypeMax; Index++) {

+    if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {

+      Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;

+      Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;

+      Configuration.SpaceDesp[Index].AddrLen      = PrivateData->ResAllocNode[Index].Length;

+    }  

+  }  

+    

+  *Resources = &Configuration;      

+  return EFI_SUCCESS;

+}

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S
new file mode 100644
index 0000000..ca484f5
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.S
@@ -0,0 +1,121 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+# 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.

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo8 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo8)

+ASM_PFX(IoReadFifo8):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register

+rep insb

+    mov     %r8, %rdi           # restore rdi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo16 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo16)

+ASM_PFX(IoReadFifo16):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register

+rep insw

+    mov     %r8, %rdi           # restore rdi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoReadFifo32 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoReadFifo32)

+ASM_PFX(IoReadFifo32):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rdi           # rdi: buffer address; r8: save register

+rep insl

+    mov     %r8, %rdi           # restore rdi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo8 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo8)

+ASM_PFX(IoWriteFifo8):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register

+rep outsb

+    mov     %r8, %rsi           # restore rsi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo16 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo16)

+ASM_PFX(IoWriteFifo16):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register

+rep outsw

+    mov     %r8, %rsi           # restore rsi

+    ret

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  IoWriteFifo32 (

+#    IN UINTN                  Port,              // rcx

+#    IN UINTN                  Count,             // rdx

+#    IN VOID                   *Buffer            // r8

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(IoWriteFifo32)

+ASM_PFX(IoWriteFifo32):

+    cld

+    xchg    %rcx, %rdx

+    xchg    %r8, %rsi           # rsi: buffer address; r8: save register

+rep outsl

+    mov     %r8, %rsi           # restore rsi

+    ret

+

diff --git a/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm
new file mode 100644
index 0000000..d16f024
--- /dev/null
+++ b/uefi/linaro-edk2/PcAtChipsetPkg/PciHostBridgeDxe/X64/IoFifo.asm
@@ -0,0 +1,125 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>

+; 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.

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo8 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo8 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi

+rep insb

+    mov     rdi, r8             ; restore rdi

+    ret

+IoReadFifo8 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo16 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo16 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi

+rep insw

+    mov     rdi, r8             ; restore rdi

+    ret

+IoReadFifo16 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoReadFifo32 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoReadFifo32 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rdi, r8             ; rdi: buffer address; r8: save rdi

+rep insd

+    mov     rdi, r8             ; restore rdi

+    ret

+IoReadFifo32 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo8 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo8 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi

+rep outsb

+    mov     rsi, r8             ; restore rsi

+    ret

+IoWriteFifo8 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo16 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo16 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi

+rep outsw

+    mov     rsi, r8             ; restore rsi

+    ret

+IoWriteFifo16 ENDP

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  IoWriteFifo32 (

+;    IN UINTN                  Port,              // rcx

+;    IN UINTN                  Size,              // rdx

+;    IN VOID                   *Buffer            // r8

+;    );

+;------------------------------------------------------------------------------

+IoWriteFifo32 PROC

+    cld

+    xchg    rcx, rdx

+    xchg    rsi, r8             ; rsi: buffer address; r8: save rsi

+rep outsd

+    mov     rsi, r8             ; restore rsi

+    ret

+IoWriteFifo32 ENDP

+

+    END

+