summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c516
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h193
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf79
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak96
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl67
7 files changed, 1003 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c
new file mode 100644
index 0000000..53fc550
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c
@@ -0,0 +1,516 @@
+/** @file
+ PCH SERIAL GPIO Driver implements the SERIAL GPIO Interface.
+ Usage model for this protocol is:
+ 1. locate this protocol by guid variable gEfiSerialGpioProtocolGuid
+ 2. Use SerialGpioRegister to register for one serial GPIO pin.
+ 3. Send data using SerialGpioSendData.
+ 4. If another GPIO need to send serial data,
+ the former one need to be unregistered using SerialGpioUnRegister since PCH have only one set of registers for serial GPIO data sending.
+ And register the new GPIO pin for Serial Gpio data sending.
+
+@copyright
+ Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchSerialGpio.h"
+
+///
+/// Global variables
+///
+UINT32 mPchGpioBase;
+
+/**
+ Register for one GPIO Pin that will be used as serial GPIO.
+ For PCH only GPIO0~31 will have the capability to be used as serail GPIO.
+ The caller of this procedure need to be very clear of whPch GPIO should be used as serail GPIO,
+ it should not be input, native, conflict with other GPIO, or Index > 31 on the caller's platform.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER SerialGpioPinIndex is out of range
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ )
+{
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ PCH_SERIES PchSeries;
+
+ if (SerialGpioPinIndex >= SERIAL_GPIO_MAX_PIN_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance->CurrentActiveSerialGpio != SERIAL_GPIO_PIN_CLEARED) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "You have to unregister the former serial GPIO %d registered, then try to register this GPIO pin %d\n",
+ SerialGpioInstance->CurrentActiveSerialGpio,
+ SerialGpioPinIndex)
+ );
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Read out values original in serial GPIO registers.
+ ///
+ if (PchSeries == PchH) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL));
+ GpioIoSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL));
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))));
+ }
+
+ GpioBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK));
+ GpioSerBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK));
+
+ SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue = GpioUseSelValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue = GpioBlinkValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue = GpioSerBlinkValue;
+ if (PchSeries == PchH) {
+ SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue = GpioIoSelValue;
+ }
+
+ ///
+ /// Modify settings in serial GPIO registers.
+ ///
+ ///
+ /// Serial GPIO will have to be selected as GPIO, not native
+ ///
+ if (PchSeries == PchH) {
+ GpioUseSelValue |= (1 << SerialGpioPinIndex);
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue |= B_PCH_GPIO_OWN0_GPIO_USE_SEL;
+ }
+
+ ///
+ /// Serial GPIO will have no Blink setting
+ ///
+ GpioBlinkValue &= (~(1 << SerialGpioPinIndex));
+
+ ///
+ /// Serial GPIO will have to enable serial Binlk setting
+ ///
+ GpioSerBlinkValue |= (1 << SerialGpioPinIndex);
+
+ ///
+ /// Serial GPIO will have to be output
+ ///
+ if (PchSeries == PchH) {
+ GpioIoSelValue &= (~(1 << SerialGpioPinIndex));
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue &= (~B_PCH_GPIO_OWN0_GPIO_IO_SEL);
+ }
+
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (PchSeries == PchH) {
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL), GpioUseSelValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL), GpioIoSelValue);
+ }
+
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))), GpioUseSelValue);
+ }
+
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK), GpioBlinkValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK), GpioSerBlinkValue);
+
+ ///
+ /// Record this GPIO index to private data structure
+ ///
+ SerialGpioInstance->CurrentActiveSerialGpio = SerialGpioPinIndex;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unregister for one GPIO Pin that has been used as serial GPIO, and recover the registers before
+ registering.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER Invalid function parameters
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioUnRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ )
+{
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ PCH_SERIES PchSeries;
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((SerialGpioPinIndex != SerialGpioInstance->CurrentActiveSerialGpio) ||
+ (SerialGpioPinIndex >= SERIAL_GPIO_MAX_PIN_NUMBER)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ GpioUseSelValue = SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue;
+ GpioBlinkValue = SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue;
+ GpioSerBlinkValue = SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue;
+
+ if (PchSeries == PchH) {
+ GpioIoSelValue = SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue;
+ }
+
+ ///
+ /// At least to clear the serial Blink property
+ ///
+ GpioSerBlinkValue &= (~(1 << SerialGpioInstance->CurrentActiveSerialGpio));
+
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Write values with original values in serial GPIO registers.
+ ///
+
+ if (PchSeries == PchH) {
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL), GpioUseSelValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL), GpioIoSelValue);
+ }
+
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))), GpioUseSelValue);
+ }
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK), GpioBlinkValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK), GpioSerBlinkValue);
+
+ ///
+ /// Clear the GPIO index in private data structure
+ ///
+ SerialGpioInstance->CurrentActiveSerialGpio = SERIAL_GPIO_PIN_CLEARED;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Execute SERIAL_GPIO commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] GpioPinIndex Index of the GPIO pin.
+ @param[in] DataRate The data rate for serail data transfering. 1 ~ SERIAL_GPIO_MAX_DATA_RATE; 1: 128ns intervals; ...; 8: 8*128 = 1024ns intervals, default value;...
+ @param[in] DataCountInByte Number of bytes of the data will be transmitted through the GPIO pin.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada sent through the GPIO pin.
+
+ @retval EFI_SUCCESS Execute succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, GPIO serial data sent failed.
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioSendData (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 GpioPinIndex,
+ IN UINT8 DataRate,
+ IN UINTN DataCountInByte,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataCountInDword;
+ UINTN DataCountLeftInByte;
+ UINTN Index;
+ UINT32 GpioSbCmdStsValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Check if the parameters are valid.
+ ///
+ if ((Buffer == NULL) ||
+ (DataRate > SERIAL_GPIO_MAX_DATA_RATE) ||
+ (GpioPinIndex != SerialGpioInstance->CurrentActiveSerialGpio)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Make sure it's safe to program the serial GPIO.
+ ///
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// set data rate
+ ///
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ GpioSbCmdStsValue &= (~B_PCH_GPIO_SB_CMDSTS_DRS_MASK);
+ GpioSbCmdStsValue |= (DataRate << 16);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ DataCountInDword = DataCountInByte / 4;
+ DataCountLeftInByte = DataCountInByte % 4;
+ for (Index = 0; Index < DataCountInDword; Index++) {
+ Status = SendSerialGpioSend (
+ This,
+ EnumSerialGpioDataDword,
+ (Buffer + Index * 4)
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ for (Index = 0; Index < DataCountLeftInByte; Index++) {
+ Status = SendSerialGpioSend (
+ This,
+ EnumSerialGpioDataByte,
+ (Buffer + DataCountInDword * 4 + Index)
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function sends the dword/word/byte through the serial GPIO pin.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] DataWidth The data width. 0: byte; 1: word; 2: reserved; 3: dword.
+ @param[in] Data Data buffer that contains the data (<= UINT32)
+
+ @retval EFI_SUCCESS SERIAL_GPIO command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+**/
+EFI_STATUS
+SendSerialGpioSend (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN SERIAL_GPIO_DATA_WIDTH DataWidth,
+ IN UINT8 *Data
+ )
+{
+ UINT32 DataInDword;
+ UINT32 GpioSbCmdStsValue;
+
+ ///
+ /// Wait the SERIAL GPIO BUSY to be cleared.
+ ///
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// set data length
+ ///
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ GpioSbCmdStsValue &= (~B_PCH_GPIO_SB_CMDSTS_DLS_MASK);
+ GpioSbCmdStsValue |= (DataWidth << 22);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ ///
+ /// Set Data
+ ///
+ DataInDword = *(UINT32 *) Data;
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_DATA), DataInDword);
+ ///
+ /// Set GO to start transmit
+ ///
+ GpioSbCmdStsValue |= B_PCH_GPIO_SB_CMDSTS_GO;
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Wait PCH serial GPIO Busy bit being cleared by PCH chipset.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS SERIAL GPIO BUSY bit is cleared.
+ @retval EFI_DEVICE_ERROR Time out while waiting the SERIAL GPIO BUSY bit to be cleared.
+ It's not safe to send next data block on the SERIAL GPIO interface.
+**/
+EFI_STATUS
+WaitForSerialGpioNotBusy (
+ VOID
+ )
+{
+ UINTN WaitTicks;
+ UINTN WaitCount;
+ UINT32 GpioSbCmdStsValue;
+
+ ///
+ /// Convert the wait period allowed into to tick count
+ ///
+ WaitCount = WAIT_TIME / WAIT_PERIOD;
+ ///
+ /// Wait for the SERIAL_GPIO cycle to complete.
+ ///
+ for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ if ((GpioSbCmdStsValue & B_PCH_GPIO_SB_CMDSTS_BUSY) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ PchPmTimerStall (WAIT_PERIOD);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Entry point for the SERIAL_GPIO host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_SUCCESS Initialization complete.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSerialGpio (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "InstallPchSerialGpio() Start\n"));
+
+ ///
+ /// Locate CPU IO protocol
+ ///
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "SERIAL GPIO Protocol not supported due to no proper PCH LPC found!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// PCH RCBA must be initialized prior to run this driver.
+ ///
+ mPchGpioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE)
+ ) & B_PCH_LPC_GPIO_BASE_BAR;
+ ASSERT (mPchGpioBase != 0);
+
+ ///
+ /// Allocate Runtime memory for the SERIAL_GPIO protocol instance.
+ ///
+ SerialGpioInstance = AllocateRuntimePool (sizeof (SERIAL_GPIO_INSTANCE));
+ if (SerialGpioInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (PchSeries == PchH) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL));
+ GpioIoSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL));
+ }
+ GpioBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK));
+ GpioSerBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK));
+ SerialGpioInstance->Signature = PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE;
+ SerialGpioInstance->Handle = NULL;
+ SerialGpioInstance->CurrentActiveSerialGpio = SERIAL_GPIO_PIN_CLEARED;
+
+ if (PchSeries == PchH) {
+ SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue = GpioUseSelValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue = GpioIoSelValue;
+ }
+ SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue = GpioBlinkValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue = GpioSerBlinkValue;
+
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioRegister = PchSerialGpioRegister;
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioSendData = PchSerialGpioSendData;
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioUnRegister = PchSerialGpioUnRegister;
+ ///
+ /// Install the EFI_SERIAL_GPIO_PROTOCOL interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(SerialGpioInstance->Handle),
+ &gEfiSerialGpioProtocolGuid,
+ &(SerialGpioInstance->SerialGpioProtocol),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (SerialGpioInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ DEBUG ((EFI_D_INFO, "InstallPchSerialGpio() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif
new file mode 100644
index 0000000..9df0226
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchSerialGpio"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SerialGpio\Dxe"
+ RefName = "PchSerialGpio"
+[files]
+"PchSerialGpio.sdl"
+"PchSerialGpio.mak"
+"PchSerialGpio.c"
+"PchSerialGpio.h"
+"PchSerialGpio.dxs"
+"PchSerialGpio.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs
new file mode 100644
index 0000000..7a9a510
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs
@@ -0,0 +1,39 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h
new file mode 100644
index 0000000..d882ada
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h
@@ -0,0 +1,193 @@
+/** @file
+ Header file for the PCH SERIAL GPIO Driver.
+
+@copyright
+ Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _PCH_SERIAL_GPIO_H_
+#define _PCH_SERIAL_GPIO_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+
+//
+// Driver Produced Protocols
+//
+#include EFI_PROTOCOL_PRODUCER (SerialGpio)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('S', 'G', 'P', 'O')
+
+#define SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL(a) \
+ CR ( \
+ a, \
+ SERIAL_GPIO_INSTANCE, \
+ SerialGpioProtocol, \
+ PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE \
+ )
+
+///
+/// Only when CurrentActiveSerialGpio == SERIAL_GPIO_PIN_CLEARED,
+/// can the next GPIO be register as serail GPIO using SerialGpioProtocol
+///
+#define SERIAL_GPIO_PIN_CLEARED 0xFF
+///
+/// This is the old values in GPIO related registers for recovery when unregister this serial GPIO pin.
+///
+typedef struct {
+ UINT32 SavedGpioUseSelValue;
+ UINT32 SavedGpioBlinkValue;
+ UINT32 SavedGpioSerBlinkValue;
+ UINT32 SavedGpioIoSelValue;
+} SERIAL_GPIO_REGISTERS_TO_RECOVER;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ UINT8 CurrentActiveSerialGpio; ///< can only have one pin at one time
+ SERIAL_GPIO_REGISTERS_TO_RECOVER RegistersToRecover;
+ EFI_SERIAL_GPIO_PROTOCOL SerialGpioProtocol;
+} SERIAL_GPIO_INSTANCE;
+
+//
+// Function prototypes used by the SERIAL_GPIO protocol.
+//
+
+/**
+ Register for one GPIO Pin that will be used as serial GPIO.
+ For PCH only GPIO0~31 will have the capability to be used as serail GPIO.
+ The caller of this procedure need to be very clear of whPch GPIO should be used as serail GPIO,
+ it should not be input, native, conflict with other GPIO, or Index > 31 on the caller's platform.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER SerialGpioPinIndex is out of range
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Unregister for one GPIO Pin that has been used as serial GPIO, and recover the registers before
+ registering.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER Invalid function parameters
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioUnRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Execute SERIAL_GPIO commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] GpioPinIndex Index of the GPIO pin.
+ @param[in] DataRate The data rate for serail data transfering. 1 ~ SERIAL_GPIO_MAX_DATA_RATE; 1: 128ns intervals; ...; 8: 8*128 = 1024ns intervals, default value;...
+ @param[in] DataCountInByte Number of bytes of the data will be transmitted through the GPIO pin.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada sent through the GPIO pin.
+
+ @retval EFI_SUCCESS Execute succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, GPIO serial data sent failed.
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioSendData (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 GpioPinIndex,
+ IN UINT8 DataRate,
+ IN UINTN DataCountInByte,
+ IN OUT UINT8 *Buffer
+ );
+
+/**
+ This function sends the dword/word/byte through the serial GPIO pin.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] DataWidth The data width. 0: byte; 1: word; 2: reserved; 3: dword.
+ @param[in] Data Data buffer that contains the data (<= UINT32)
+
+ @retval EFI_SUCCESS SERIAL_GPIO command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+**/
+EFI_STATUS
+SendSerialGpioSend (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN SERIAL_GPIO_DATA_WIDTH DataWidth,
+ IN UINT8 *Data
+ );
+
+/**
+ Wait PCH serial GPIO Busy bit being cleared by PCH chipset.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS SERIAL GPIO BUSY bit is cleared.
+ @retval EFI_DEVICE_ERROR Time out while waiting the SERIAL GPIO BUSY bit to be cleared.
+ It's not safe to send next data block on the SERIAL GPIO interface.
+**/
+EFI_STATUS
+WaitForSerialGpioNotBusy (
+ VOID
+ );
+
+/**
+ Entry point for the SERIAL_GPIO host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_SUCCESS Initialization complete.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSerialGpio (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf
new file mode 100644
index 0000000..508c09d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf
@@ -0,0 +1,79 @@
+## @file
+# Component description file for the PCH serial GPIO driver.
+#
+#@copyright
+# Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchSerialGpio
+FILE_GUID = FC1B7640-3466-4c06-B1CC-1C935394B5C2
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSerialGpio.h
+ PchSerialGpio.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSerialGpio.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSerialGpio
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak
new file mode 100644
index 0000000..21383c0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak
@@ -0,0 +1,96 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.mak 2 2/24/12 2:20a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:20a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.mak $
+#
+# 2 2/24/12 2:20a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSerialGpio Driver
+#---------------------------------------------------------------------------
+EDK : PchSerialGpio
+PchSerialGpio : $(BUILD_DIR)\PchSerialGpio.mak PchSerialGpioBin
+
+$(BUILD_DIR)\PchSerialGpio.mak : $(PchSerialGpio_DIR)\$(@B).cif $(PchSerialGpio_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSerialGpio_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSerialGpio_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSerialGpio_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSerialGpio"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSerialGpio_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)
+
+PchSerialGpioBin: $(PchSerialGpio_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSerialGpio.mak all \
+ "MY_INCLUDES=$(PchSerialGpio_INCLUDES)"\
+ "MY_DEFINES=$(PchSerialGpio_DEFINES)"\
+ GUID=FC1B7640-3466-4c06-B1CC-1C935394B5C2\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchSerialGpio_DIR)\PchSerialGpio.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl
new file mode 100644
index 0000000..d7095d3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.sdl 1 2/08/12 9:15a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:15a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.sdl $
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSerialGpio_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSerialGpio support in Project"
+End
+
+PATH
+ Name = "PchSerialGpio_DIR"
+ Help = "PchSerialGpio file source directory"
+End
+
+MODULE
+ File = "PchSerialGpio.mak"
+ Help = "Includes PchSerialGpio.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSerialGpio.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************