diff options
author | Michael Kinney <michael.d.kinney@intel.com> | 2015-12-15 19:22:23 +0000 |
---|---|---|
committer | mdkinney <mdkinney@Edk2> | 2015-12-15 19:22:23 +0000 |
commit | 9b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164 (patch) | |
tree | bb30f13e652143e0ac74e589e908ca2a1782da73 /QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe | |
parent | 46ff196fde4882fca1a0210f7df9166d8832ad06 (diff) | |
download | edk2-platforms-9b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164.tar.xz |
QuarkSocPkg: Add new package for Quark SoC X1000
Changes for V4
==============
1) Remove Unicode character from C source file
2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
from QuarkPlatformPkg commit to QuarkSocPkg commit
Changes for V2
==============
1) Sync with new APIs in SmmCpuFeaturesLib class
2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
3) Remove PCI serial driver from QuarkSocPkg
4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg
5) Convert all UNI files to utf-8
6) Replace tabs with spaces and remove trailing spaces
7) Add License.txt
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe')
11 files changed, 2431 insertions, 0 deletions
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h new file mode 100644 index 0000000000..e0fa485640 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h @@ -0,0 +1,55 @@ +/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+
+//
+// The protocols, PPI and GUID definitions for this module
+//
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/LegacyRegion2.h>
+#include <Protocol/SmbusHc.h>
+#include <Protocol/QncS3Support.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/S3IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/IntelQNCLib.h>
+#include <Library/QNCAccessLib.h>
+#include <AcpiCpuData.h>
+
+extern EFI_HANDLE gQNCInitImageHandle;
+extern QNC_DEVICE_ENABLES mQNCDeviceEnables;
+
+#endif
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c new file mode 100644 index 0000000000..a5927ecc40 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c @@ -0,0 +1,618 @@ +/** @file
+Implementation for SMBus DXE driver entry point and SMBus Host
+Controller protocol.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+#include "DxeQNCSmbus.h"
+
+//
+// Interface defintion of SMBUS Host Controller Protocol.
+//
+EFI_SMBUS_HC_PROTOCOL mSmbusHc = {
+ SmbusExecute,
+ SmbusArpDevice,
+ SmbusGetArpMap,
+ SmbusNotify
+};
+
+//
+// Handle to install SMBus Host Controller protocol.
+//
+EFI_HANDLE mSmbusHcHandle = NULL;
+UINT8 mDeviceMapEntries = 0;
+EFI_SMBUS_DEVICE_MAP mDeviceMap[MAX_SMBUS_DEVICES];
+UINT8 mPlatformNumRsvd = 0;
+UINT8 *mPlatformAddrRsvd = NULL;
+
+//
+// These addresses are reserved by the SMBus 2.0 specification
+//
+UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = {
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x18, 0x50, 0x6E, 0xC2,
+ 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE
+};
+
+
+/**
+ Gets Io port base address of Smbus Host Controller.
+
+ This internal function depends on a feature flag named PcdIchSmbusFixedIoPortBaseAddress
+ to retrieve Smbus Io port base. If that feature flag is true, it will get Smbus Io port base
+ address from a preset Pcd entry named PcdIchSmbusIoPortBaseAddress; otherwise, it will always
+ read Pci configuration space to get that value in each Smbus bus transaction.
+
+ @return The Io port base address of Smbus host controller.
+
+**/
+UINTN
+GetSmbusIoPortBaseAddress (
+ VOID
+ )
+{
+ UINTN IoPortBaseAddress;
+
+ if (FeaturePcdGet (PcdSmbaIoBaseAddressFixed)) {
+ IoPortBaseAddress = (UINTN) PcdGet16 (PcdSmbaIoBaseAddress);
+ } else {
+ IoPortBaseAddress = (UINTN) LpcPciCfg32 (R_QNC_LPC_SMBUS_BASE) & B_QNC_LPC_SMBUS_BASE_MASK;
+ }
+
+ //
+ // Make sure that the IO port base address has been properly set.
+ //
+ ASSERT (IoPortBaseAddress != 0);
+
+ return IoPortBaseAddress;
+}
+
+
+VOID
+InitializeInternal (
+ )
+{
+ UINTN IoPortBaseAddress;
+
+ IoPortBaseAddress = GetSmbusIoPortBaseAddress ();
+
+ //
+ // Step1: Enable QNC SMBUS I/O space.
+ //
+ LpcPciCfg32Or(R_QNC_LPC_SMBUS_BASE, B_QNC_LPC_SMBUS_BASE_EN);
+
+ //
+ // Step2: Clear Status Register before anyone uses the interfaces.
+ //
+ IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HSTS, B_QNC_SMBUS_HSTS_ALL);
+
+ //
+ // Step3: Program the correct smbus clock
+ //
+ IoWrite8 (IoPortBaseAddress + R_QNC_SMBUS_HCLK, V_QNC_SMBUS_HCLK_100KHZ);
+}
+
+
+
+
+BOOLEAN
+IsAddressAvailable (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ )
+{
+ UINT8 Index;
+
+ //
+ // See if we have already assigned this address to a device
+ //
+ for (Index = 0; Index < mDeviceMapEntries; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress ==
+ mDeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+ return FALSE;
+ }
+ }
+
+ //
+ // See if this address is claimed by a platform non-ARP-capable device
+ //
+ for (Index = 0; Index < mPlatformNumRsvd; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == mPlatformAddrRsvd[Index]) {
+ return FALSE;
+ }
+ }
+
+ //
+ // See if this is a reserved address
+ //
+ for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress == (UINTN) mReservedAddress[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+EFI_STATUS
+GetNextAvailableAddress (
+ IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ for (SlaveAddress->SmbusDeviceAddress = 0x03;
+ SlaveAddress->SmbusDeviceAddress < 0x7F;
+ SlaveAddress->SmbusDeviceAddress++
+ ) {
+ if (IsAddressAvailable (*SlaveAddress)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+EFI_STATUS
+SmbusPrepareToArp (
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer;
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = 1;
+ Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+ Status = Execute (
+ SlaveAddress,
+ 0,
+ EfiSmbusSendByte,
+ TRUE,
+ &Length,
+ &Buffer
+ );
+ return Status;
+}
+
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = Execute (
+ SlaveAddress,
+ SMBUS_DATA_GET_UDID_GENERAL,
+ EfiSmbusReadBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ if (!EFI_ERROR(Status)) {
+ if (Length == SMBUS_GET_UDID_LENGTH) {
+ DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+ DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+ DeviceMap->SmbusDeviceUdid.VendorId = (UINT16)((Buffer[2] << 8) + Buffer[3]);
+ DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16)((Buffer[4] << 8) + Buffer[5]);
+ DeviceMap->SmbusDeviceUdid.Interface = (UINT16)((Buffer[6] << 8) + Buffer[7]);
+ DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16)((Buffer[8] << 8) + Buffer[9]);
+ DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16)((Buffer[10] << 8) + Buffer[11]);
+ DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32)((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+ DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8)(Buffer[16] >> 1);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+SmbusAssignAddress (
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+ Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+ Buffer[2] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+ Buffer[3] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorId);
+ Buffer[4] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+ Buffer[5] = (UINT8)(DeviceMap->SmbusDeviceUdid.DeviceId);
+ Buffer[6] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface >> 8);
+ Buffer[7] = (UINT8)(DeviceMap->SmbusDeviceUdid.Interface);
+ Buffer[8] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+ Buffer[9] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+ Buffer[10] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+ Buffer[11] = (UINT8)(DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+ Buffer[12] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+ Buffer[13] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+ Buffer[14] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+ Buffer[15] = (UINT8)(DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+ Buffer[16] = (UINT8)(DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = Execute (
+ SlaveAddress,
+ SMBUS_DATA_ASSIGN_ADDRESS,
+ EfiSmbusWriteBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+ return Status;
+}
+
+
+EFI_STATUS
+SmbusFullArp (
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ Status = SmbusPrepareToArp ();
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ //
+ // ARP is complete
+ //
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+ }
+
+ //
+ // Main loop to ARP all ARP-capable devices
+ //
+ do {
+ CurrentDeviceMap = &mDeviceMap[mDeviceMapEntries];
+ Status = SmbusGetUdidGeneral (CurrentDeviceMap);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+ //
+ // If address is unassigned, assign it
+ //
+ Status = GetNextAvailableAddress (
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+ //
+ // if address is not fixed, check if the current address is available
+ //
+ if (!IsAddressAvailable (
+ CurrentDeviceMap->SmbusDeviceAddress
+ )) {
+ //
+ // if currently assigned address is already used, get a new one
+ //
+ Status = GetNextAvailableAddress (
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ Status = SmbusAssignAddress (CurrentDeviceMap);
+ if (EFI_ERROR(Status)) {
+ //
+ // If there was a device error, just continue on and try again.
+ // Other errors should be reported.
+ //
+ if (Status != EFI_DEVICE_ERROR) {
+ return Status;
+ }
+ } else {
+ //
+ // If there was no error, the address was assigned and we must update our
+ // records.
+ //
+ mDeviceMapEntries++;
+ }
+
+ } while (mDeviceMapEntries < MAX_SMBUS_DEVICES);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmbusDirectedArp (
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ if (mDeviceMapEntries >= MAX_SMBUS_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap = &mDeviceMap[mDeviceMapEntries];
+
+ //
+ // Find an available address to assign
+ //
+ Status = GetNextAvailableAddress (
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities;
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId;
+
+ Status = SmbusAssignAddress (CurrentDeviceMap);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ mDeviceMapEntries++;
+ SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN CONST EFI_SMBUS_DEVICE_COMMAND Command,
+ IN CONST EFI_SMBUS_OPERATION Operation,
+ IN CONST BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ InitializeInternal ();
+ return Execute (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+}
+
+/**
+ Sets the SMBus slave device addresses for the device with a given unique ID or enumerates the
+ entire bus.
+
+ The ArpDevice() function provides a standard way for a device driver to enumerate the entire
+ SMBus or specific devices on the bus.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param ArpAll A Boolean expression that indicates if the host drivers need to
+ enumerate all the devices or enumerate only the device that is
+ identified by SmbusUdid. If ArpAll is TRUE, SmbusUdid and
+ SlaveAddress are optional. If ArpAll is FALSE, ArpDevice will
+ enumerate SmbusUdid and the address will be at SlaveAddress.
+ @param SmbusUdid The Unique Device Identifier (UDID) that is associated with this
+ device.
+ @param SlaveAddress The SMBus slave address that is associated with an SMBus UDID.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_UNSUPPORTED The corresponding SMBus operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+ )
+{
+ InitializeInternal ();
+
+ if (ArpAll) {
+ return SmbusFullArp ();
+ } else {
+ if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return SmbusDirectedArp ((EFI_SMBUS_UDID *)SmbusUdid, SlaveAddress);
+ }
+}
+
+/**
+ Returns a pointer to the Address Resolution Protocol (ARP) map that contains the ID/address pair
+ of the slave devices that were enumerated by the SMBus host controller driver.
+
+ The GetArpMap() function returns the mapping of all the SMBus devices that were enumerated by the
+ SMBus host driver.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param Length Size of the buffer that contains the SMBus device map.
+ @param SmbusDeviceMap The pointer to the device map as enumerated by the SMBus
+ controller driver.
+
+ @retval EFI_SUCCESS The SMBus returned the current device map.
+ @retval EFI_UNSUPPORTED The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ *Length = mDeviceMapEntries;
+ *SmbusDeviceMap = mDeviceMap;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Allows a device driver to register for a callback when the bus driver detects a state that it
+ needs to propagate to other drivers that are registered for a callback.
+
+ The Notify() function registers all the callback functions to allow the bus driver to call these
+ functions when the SlaveAddress/Data pair happens.
+ If NotifyFunction is NULL, then ASSERT ().
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBUS hardware address to which the SMBUS device is
+ preassigned or allocated.
+ @param Data Data of the SMBus host notify command that the caller wants to be
+ called.
+ @param NotifyFunction The function to call when the bus driver detects the SlaveAddress
+ and Data pair.
+
+ @retval EFI_SUCCESS NotifyFunction was registered.
+ @retval EFI_UNSUPPORTED The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN CONST UINTN Data,
+ IN CONST EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Entry point to the DXE Driver that produces the SMBus Host Controller Protocol.
+
+ @param ImageHandle ImageHandle of the loaded driver.
+ @param SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point of SMBus DXE driver is executed successfully.
+ @retval !EFI_SUCESS Some error occurs in the entry point of SMBus DXE driver.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeQNCSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mPlatformNumRsvd = (UINT8)PcdGet32 (PcdPlatformSmbusAddrNum);
+ mPlatformAddrRsvd = (UINT8 *)(UINTN) PcdGet64 (PcdPlatformSmbusAddrTable);
+
+ //
+ // Install SMBus Host Controller protocol interface.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusHcHandle,
+ &gEfiSmbusHcProtocolGuid,
+ &mSmbusHc,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h new file mode 100644 index 0000000000..306576bd8b --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h @@ -0,0 +1,211 @@ +/** @file
+Header file for the defintions used in SMBus DXE driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 _DXE_QNC_SMBUS_H_
+#define _DXE_QNC_SMBUS_H_
+#include "CommonHeader.h"
+
+#include "QNCSmbus.h"
+
+#define MAX_SMBUS_DEVICES 107 // Max number of SMBus devices (7 bit
+ // address yields 128 combinations but 21
+ // of those are reserved)
+
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+#define STALL_TIME 1000000 // 1,000,000 microseconds = 1 second
+#define BUS_TRIES 3 // How many times to retry on Bus Errors
+#define SMBUS_NUM_RESERVED 21 // Number of device addresses that are
+ // reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP 0xC2 >> 1
+#define SMBUS_DATA_PREPARE_TO_ARP 0x01
+#define SMBUS_DATA_RESET_DEVICE 0x02
+#define SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define SMBUS_DATA_ASSIGN_ADDRESS 0x04
+#define SMBUS_GET_UDID_LENGTH 17 // 16 byte UDID + 1 byte address
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN CONST EFI_SMBUS_DEVICE_COMMAND Command,
+ IN CONST EFI_SMBUS_OPERATION Operation,
+ IN CONST BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Sets the SMBus slave device addresses for the device with a given unique ID or enumerates the
+ entire bus.
+
+ The ArpDevice() function provides a standard way for a device driver to enumerate the entire
+ SMBus or specific devices on the bus.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param ArpAll A Boolean expression that indicates if the host drivers need to
+ enumerate all the devices or enumerate only the device that is
+ identified by SmbusUdid. If ArpAll is TRUE, SmbusUdid and
+ SlaveAddress are optional. If ArpAll is FALSE, ArpDevice will
+ enumerate SmbusUdid and the address will be at SlaveAddress.
+ @param SmbusUdid The Unique Device Identifier (UDID) that is associated with this
+ device.
+ @param SlaveAddress The SMBus slave address that is associated with an SMBus UDID.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_UNSUPPORTED The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+ );
+
+/**
+ Returns a pointer to the Address Resolution Protocol (ARP) map that contains the ID/address pair
+ of the slave devices that were enumerated by the SMBus host controller driver.
+
+ The GetArpMap() function returns the mapping of all the SMBus devices that were enumerated by the
+ SMBus host driver.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param Length Size of the buffer that contains the SMBus device map.
+ @param SmbusDeviceMap The pointer to the device map as enumerated by the SMBus
+ controller driver.
+
+ @retval EFI_SUCCESS The SMBus returned the current device map.
+ @retval EFI_UNSUPPORTED The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Allows a device driver to register for a callback when the bus driver detects a state that it
+ needs to propagate to other drivers that are registered for a callback.
+
+ The Notify() function registers all the callback functions to allow the bus driver to call these
+ functions when the SlaveAddress/Data pair happens.
+ If NotifyFunction is NULL, then ASSERT ().
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBUS hardware address to which the SMBUS device is
+ preassigned or allocated.
+ @param Data Data of the SMBus host notify command that the caller wants to be
+ called.
+ @param NotifyFunction The function to call when the bus driver detects the SlaveAddress
+ and Data pair.
+
+ @retval EFI_SUCCESS NotifyFunction was registered.
+ @retval EFI_UNSUPPORTED The corresponding operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN CONST UINTN Data,
+ IN CONST EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+/**
+ Entry point to the DXE Driver that produces the SMBus Host Controller Protocol.
+
+ @param ImageHandle ImageHandle of the loaded driver.
+ @param SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point of SMBus DXE driver is executed successfully.
+ @retval !EFI_SUCESS Some error occurs in the entry point of SMBus DXE driver.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeQNCSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c new file mode 100644 index 0000000000..28c79b0ebb --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c @@ -0,0 +1,243 @@ +/** @file
+QNC Legacy Region Driver
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+#include "LegacyRegion.h"
+
+//
+// Handle used to install the Legacy Region Protocol
+//
+EFI_HANDLE mLegacyRegion2Handle = NULL;
+
+//
+// Instance of the Legacy Region Protocol to install into the handle database
+//
+EFI_LEGACY_REGION2_PROTOCOL mLegacyRegion2 = {
+ LegacyRegion2Decode,
+ LegacyRegion2Lock,
+ LegacyRegion2BootLock,
+ LegacyRegion2Unlock,
+ LegacyRegionGetInfo
+};
+
+
+/**
+ Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
+
+ If the On parameter evaluates to TRUE, this function enables memory reads in the address range
+ Start to (Start + Length - 1).
+ If the On parameter evaluates to FALSE, this function disables memory reads in the address range
+ Start to (Start + Length - 1).
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose attributes
+ should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address
+ was not aligned to a region's starting address or if the length
+ was greater than the number of bytes in the first region.
+ @param On[in] Decode / Non-Decode flag.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Decode (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity,
+ IN BOOLEAN *On
+ )
+{
+ return QNCLegacyRegionManipulation (Start, Length, On, NULL, Granularity);
+}
+
+
+/**
+ Modify the hardware to disallow memory attribute changes in a region.
+
+ This function makes the attributes of a region read only. Once a region is boot-locked with this
+ function, the read and write attributes of that region cannot be changed until a power cycle has
+ reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+ @retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in
+ a way that will not affect memory regions outside the legacy memory
+ region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2BootLock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ )
+{
+ if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Modify the hardware to disallow memory writes in a region.
+
+ This function changes the attributes of a memory range to not allow writes.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Lock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ )
+{
+ BOOLEAN WriteEnable;
+
+ WriteEnable = FALSE;
+ return QNCLegacyRegionManipulation (Start, Length, NULL, &WriteEnable, Granularity);
+}
+
+
+/**
+ Modify the hardware to allow memory writes in a region.
+
+ This function changes the attributes of a memory range to allow writes.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Unlock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ )
+{
+ BOOLEAN WriteEnable;
+
+ WriteEnable = TRUE;
+ return QNCLegacyRegionManipulation (Start, Length, NULL, &WriteEnable, Granularity);
+}
+
+/**
+ Get region information for the attributes of the Legacy Region.
+
+ This function is used to discover the granularity of the attributes for the memory in the legacy
+ region. Each attribute may have a different granularity and the granularity may not be the same
+ for all memory ranges in the legacy region.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor
+ buffer.
+ @param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy
+ region information is deposited. This buffer will contain a list of
+ DescriptorCount number of region descriptors. This function will
+ provide the memory for the buffer.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegionGetInfo (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ OUT UINT32 *DescriptorCount,
+ OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor
+ )
+{
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Entry point to the DXE Driver that produces the Legacy Region Protocol.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCESS The return status from the last driver entry point in the list.
+
+**/
+EFI_STATUS
+LegacyRegionInit (
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install the Legacy Region Protocol on a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mLegacyRegion2Handle,
+ &gEfiLegacyRegion2ProtocolGuid, &mLegacyRegion2,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h new file mode 100644 index 0000000000..7bcb884a33 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h @@ -0,0 +1,204 @@ +/** @file
+The header file legacy region initialization in QNC DXE component.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 _LEGACY_REGION_H_
+#define _LEGACY_REGION_H_
+#include "CommonHeader.h"
+
+#include <IndustryStandard/Pci.h>
+
+#define LEGACY_REGION_INSTANCE_SIGNATURE SIGNATURE_32('R','E','G','N')
+
+typedef struct {
+ UINT32 Signature;
+
+ EFI_HANDLE Handle;
+ EFI_LEGACY_REGION2_PROTOCOL LegacyRegion2;
+ EFI_HANDLE ImageHandle;
+
+ //
+ // Protocol for PAM register access
+ //
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+} LEGACY_REGION_INSTANCE;
+
+#define LEGACY_REGION_INSTANCE_FROM_THIS(this) \
+ CR(this, LEGACY_REGION_INSTANCE, LegacyRegion2, LEGACY_REGION_INSTANCE_SIGNATURE)
+
+
+EFI_STATUS
+LegacyRegionManipluateRegion (
+ IN LEGACY_REGION_INSTANCE *Private
+ );
+
+EFI_STATUS
+LegacyRegionInit (
+ VOID
+ );
+
+/**
+ Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
+
+ If the On parameter evaluates to TRUE, this function enables memory reads in the address range
+ Start to (Start + Length - 1).
+ If the On parameter evaluates to FALSE, this function disables memory reads in the address range
+ Start to (Start + Length - 1).
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose attributes
+ should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address
+ was not aligned to a region's starting address or if the length
+ was greater than the number of bytes in the first region.
+ @param On[in] Decode / Non-Decode flag.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Decode (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity,
+ IN BOOLEAN *On
+ );
+
+/**
+ Modify the hardware to disallow memory writes in a region.
+
+ This function changes the attributes of a memory range to not allow writes.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Lock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ );
+
+/**
+ Modify the hardware to disallow memory attribute changes in a region.
+
+ This function makes the attributes of a region read only. Once a region is boot-locked with this
+ function, the read and write attributes of that region cannot be changed until a power cycle has
+ reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+ @retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in
+ a way that will not affect memory regions outside the legacy memory
+ region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2BootLock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ );
+
+/**
+ Modify the hardware to allow memory writes in a region.
+
+ This function changes the attributes of a memory range to allow writes.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param Start[in] The beginning of the physical address of the region whose
+ attributes should be modified.
+ @param Length[in] The number of bytes of memory whose attributes should be modified.
+ The actual number of bytes modified may be greater than the number
+ specified.
+ @param Granularity[out] The number of bytes in the last region affected. This may be less
+ than the total number of bytes affected if the starting address was
+ not aligned to a region's starting address or if the length was
+ greater than the number of bytes in the first region.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegion2Unlock (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ IN UINT32 Start,
+ IN UINT32 Length,
+ OUT UINT32 *Granularity
+ );
+
+/**
+ Get region information for the attributes of the Legacy Region.
+
+ This function is used to discover the granularity of the attributes for the memory in the legacy
+ region. Each attribute may have a different granularity and the granularity may not be the same
+ for all memory ranges in the legacy region.
+
+ @param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
+ @param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor
+ buffer.
+ @param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy
+ region information is deposited. This buffer will contain a list of
+ DescriptorCount number of region descriptors. This function will
+ provide the memory for the buffer.
+
+ @retval EFI_SUCCESS The region's attributes were successfully modified.
+ @retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyRegionGetInfo (
+ IN EFI_LEGACY_REGION2_PROTOCOL *This,
+ OUT UINT32 *DescriptorCount,
+ OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor
+ );
+
+#endif //_QNC_LEGACY_REGION_H_
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c new file mode 100644 index 0000000000..c434067f72 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c @@ -0,0 +1,527 @@ +/** @file
+QuarkNcSocId module initialization module
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+#include "LegacyRegion.h"
+#include "DxeQNCSmbus.h"
+
+#include "QNCInit.h"
+
+//
+// Definitions
+//
+#define QNC_RESERVED_ITEM_IO 0
+#define QNC_RESERVED_ITEM_MEMORYIO 1
+#define DXE_DEVICE_DISABLED 0
+#define DXE_DEVICE_ENABLED 1
+
+typedef struct _QNC_SPACE_TABLE_ITEM {
+ UINTN IoOrMemory;
+ UINTN Type;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ UINTN Alignment;
+ BOOLEAN RuntimeOrNot;
+} QNC_SPACE_TABLE_ITEM;
+
+typedef struct {
+ ACPI_CPU_DATA AcpuCpuData;
+ MTRR_SETTINGS MtrrTable;
+ IA32_DESCRIPTOR GdtrProfile;
+ IA32_DESCRIPTOR IdtrProfile;
+ CPU_REGISTER_TABLE RegisterTable;
+ CPU_REGISTER_TABLE PreSmmInitRegisterTable;
+} ACPI_CPU_DATA_EX;
+
+//
+// Spaces to be reserved in GCD
+// Expand it to add more
+//
+const QNC_SPACE_TABLE_ITEM mQNCReservedSpaceTable[] = {
+ {
+ QNC_RESERVED_ITEM_MEMORYIO,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ FixedPcdGet64 (PcdIoApicBaseAddress),
+ FixedPcdGet64 (PcdIoApicSize),
+ 0,
+ FALSE
+ },
+ {
+ QNC_RESERVED_ITEM_MEMORYIO,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ FixedPcdGet64 (PcdHpetBaseAddress),
+ FixedPcdGet64 (PcdHpetSize),
+ 0,
+ FALSE
+ }
+};
+
+//
+// Global variable for ImageHandle of QNCInit driver
+//
+EFI_HANDLE gQNCInitImageHandle;
+QNC_DEVICE_ENABLES mQNCDeviceEnables;
+
+
+VOID
+QNCInitializeResource (
+ VOID
+ );
+
+EFI_STATUS
+InitializeQNCPolicy (
+ VOID
+ );
+
+/**
+ Allocate EfiACPIMemoryNVS below 4G memory address.
+
+ This function allocates EfiACPIMemoryNVS below 4G memory address.
+
+ @param Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+VOID *
+AllocateAcpiNvsMemoryBelow4G (
+ IN UINTN Size
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID* Buffer;
+
+ Pages = EFI_SIZE_TO_PAGES (Size);
+ Address = 0xffffffff;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ Pages,
+ &Address
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+/**
+ Prepare ACPI NVS memory below 4G memory for use of S3 resume.
+
+ This function allocates ACPI NVS memory below 4G memory for use of S3 resume,
+ and saves data into the memory region.
+
+**/
+VOID
+SaveCpuS3Data (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ ACPI_CPU_DATA_EX *AcpiCpuDataEx;
+ ACPI_CPU_DATA *AcpiCpuData;
+ UINTN GdtSize;
+ UINTN IdtSize;
+ VOID *Gdt;
+ VOID *Idt;
+
+ //
+ // Allocate ACPI NVS memory below 4G memory for use of S3 resume.
+ //
+ AcpiCpuDataEx = AllocateAcpiNvsMemoryBelow4G (sizeof (ACPI_CPU_DATA_EX));
+ AcpiCpuData = &AcpiCpuDataEx->AcpuCpuData;
+
+ //
+ //
+ //
+ AcpiCpuData->NumberOfCpus = 1;
+ AcpiCpuData->StackSize = PcdGet32 (PcdCpuApStackSize);
+ AcpiCpuData->ApMachineCheckHandlerBase = 0;
+ AcpiCpuData->ApMachineCheckHandlerSize = 0;
+ AcpiCpuData->GdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->GdtrProfile;
+ AcpiCpuData->IdtrProfile = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->IdtrProfile;
+ AcpiCpuData->MtrrTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->MtrrTable;
+ AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->RegisterTable;
+ AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS) (UINTN) &AcpiCpuDataEx->PreSmmInitRegisterTable;
+
+ //
+ // Allocate stack space for all CPUs
+ //
+ AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateAcpiNvsMemoryBelow4G (AcpiCpuData->NumberOfCpus * AcpiCpuData->StackSize);
+
+ //
+ // Get MTRR settings from currently executing CPU
+ //
+ MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
+
+ //
+ // Get the BSP's data of GDT and IDT
+ //
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->GdtrProfile);
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &AcpiCpuDataEx->IdtrProfile);
+
+ //
+ // Allocate GDT and IDT in ACPI NVS and copy in current GDT and IDT contents
+ //
+ GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;
+ IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;
+ Gdt = AllocateAcpiNvsMemoryBelow4G (GdtSize + IdtSize);
+ Idt = (VOID *)((UINTN)Gdt + GdtSize);
+ CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);
+ CopyMem (Idt, (VOID *)AcpiCpuDataEx->IdtrProfile.Base, IdtSize);
+ AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;
+ AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;
+
+ //
+ // No RegisterTable entries
+ //
+ AcpiCpuDataEx->RegisterTable.TableLength = 0;
+
+ //
+ // No PreSmmInitRegisterTable entries
+ //
+ AcpiCpuDataEx->PreSmmInitRegisterTable.TableLength = 0;
+
+ //
+ // Set the base address of CPU S3 data to PcdCpuS3DataAddress
+ //
+ Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ The entry function for QNCInit driver.
+
+ This function just call initialization function for PciHostBridge,
+ LegacyRegion and QNCSmmAccess module.
+
+ @param ImageHandle The driver image handle for GmchInit driver
+ @param SystemTable The pointer to System Table
+
+ @retval EFI_SUCCESS Success to initialize every module for GMCH driver.
+ @return EFI_STATUS The status of initialization work.
+
+**/
+EFI_STATUS
+EFIAPI
+QNCInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ S3BootScriptSaveInformationAsciiString (
+ "QNCInitDxeEntryBegin"
+ );
+
+ gQNCInitImageHandle = ImageHandle;
+
+ mQNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);
+
+
+ //
+ // Initialize PCIE root ports
+ //
+ Status = QncInitRootPorts ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "QNC Root Port initialization is failed!\n"));
+ return Status;
+ }
+
+ Status = LegacyRegionInit ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "QNC LegacyRegion initialization is failed!\n"));
+ return Status;
+ }
+
+
+ Status = InitializeQNCPolicy ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "QNC Policy initialization is failed!\n"));
+ return Status;
+ }
+
+ Status = InitializeQNCSmbus (ImageHandle,SystemTable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "QNC Smbus driver is failed!\n"));
+ return Status;
+ }
+
+ QNCInitializeResource ();
+
+ SaveCpuS3Data ();
+
+ S3BootScriptSaveInformationAsciiString (
+ "QNCInitDxeEntryEnd"
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Reserve I/O or memory space in GCD
+
+ @param IoOrMemory Switch of I/O or memory.
+ @param GcdType Type of the space.
+ @param BaseAddress Base address of the space.
+ @param Length Length of the space.
+ @param Alignment Align with 2^Alignment
+ @param RuntimeOrNot For runtime usage or not
+ @param ImageHandle Handle for the image of this driver.
+
+ @retval EFI_SUCCESS Reserve successful
+**/
+EFI_STATUS
+QNCReserveSpaceInGcd(
+ IN UINTN IoOrMemory,
+ IN UINTN GcdType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINTN Alignment,
+ IN BOOLEAN RuntimeOrNot,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ if (IoOrMemory == QNC_RESERVED_ITEM_MEMORYIO) {
+ Status = gDS->AddMemorySpace (
+ GcdType,
+ BaseAddress,
+ Length,
+ EFI_MEMORY_UC
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ EFI_D_ERROR,
+ "Failed to add memory space :0x%x 0x%x\n",
+ BaseAddress,
+ Length
+ ));
+ }
+ ASSERT_EFI_ERROR (Status);
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ GcdType,
+ Alignment,
+ Length,
+ &BaseAddress,
+ ImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (RuntimeOrNot) {
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ Status = gDS->AddIoSpace (
+ GcdType,
+ BaseAddress,
+ Length
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAddress,
+ GcdType,
+ Alignment,
+ Length,
+ &BaseAddress,
+ ImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ return Status;
+}
+
+
+/**
+ Initialize the memory and io resource which belong to QNC.
+ 1) Report and allocate all BAR's memory to GCD.
+ 2) Report PCI memory and I/O space to GCD.
+ 3) Set memory attribute for <1M memory space.
+**/
+VOID
+QNCInitializeResource (
+ )
+{
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_STATUS Status;
+ UINT64 ExtraRegionLength;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+ UINTN Index;
+
+ // Report TSEG range
+ // This range maybe has been reportted in PEI phase via Resource Hob.
+ //
+ QNCGetTSEGMemoryRange (&BaseAddress, &ExtraRegionLength);
+ if (ExtraRegionLength != 0) {
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &Descriptor);
+ if (Status == EFI_NOT_FOUND) {
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ BaseAddress,
+ ExtraRegionLength,
+ EFI_MEMORY_UC
+ );
+ }
+ }
+
+ //
+ // < 1M resource setting. The memory ranges <1M has been added into GCD via
+ // resource hob produced by PEI phase. Here will set memory attribute of these
+ // ranges for DXE phase.
+ //
+
+ //
+ // Dos Area (0 ~ 0x9FFFFh)
+ //
+ Status = gDS->GetMemorySpaceDescriptor (0, &Descriptor);
+ DEBUG ((
+ EFI_D_INFO,
+ "DOS Area Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+ Descriptor.BaseAddress,
+ Descriptor.Length,
+ Descriptor.Attributes
+ ));
+ ASSERT_EFI_ERROR (Status);
+ Status = gDS->SetMemorySpaceAttributes(
+ 0,
+ 0xA0000,
+ EFI_MEMORY_WB
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Default SMRAM UnCachable until SMBASE relocated.
+ //
+ Status = gDS->SetMemorySpaceAttributes(
+ 0x30000,
+ 0x10000,
+ EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Default SMM ABSEG area. (0xA0000 ~ 0xBFFFF)
+ //
+ Status = gDS->GetMemorySpaceDescriptor (0xA0000, &Descriptor);
+ DEBUG ((
+ EFI_D_INFO,
+ "ABSEG Memory: base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+ Descriptor.BaseAddress,
+ Descriptor.Length,
+ Descriptor.Attributes
+ ));
+ ASSERT_EFI_ERROR (Status);
+ Status = gDS->SetMemorySpaceAttributes(
+ 0xA0000,
+ 0x20000,
+ EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Expansion BIOS area.
+ //
+ Status = gDS->GetMemorySpaceDescriptor (0xC0000, &Descriptor);
+ DEBUG ((
+ EFI_D_INFO,
+ "Memory base = 0x%x, length = 0x%x, attribute = 0x%x\n",
+ Descriptor.BaseAddress,
+ Descriptor.Length,
+ Descriptor.Attributes
+ ));
+ ASSERT_EFI_ERROR (Status);
+ Status = gDS->SetMemorySpaceAttributes(
+ 0xC0000,
+ 0x30000,
+ EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Report other IO resources from mQNCReservedSpaceTable in GCD
+ //
+ for (Index = 0; Index < sizeof (mQNCReservedSpaceTable) / sizeof (QNC_SPACE_TABLE_ITEM); Index++) {
+ Status = QNCReserveSpaceInGcd (
+ mQNCReservedSpaceTable[Index].IoOrMemory,
+ mQNCReservedSpaceTable[Index].Type,
+ mQNCReservedSpaceTable[Index].BaseAddress,
+ mQNCReservedSpaceTable[Index].Length,
+ mQNCReservedSpaceTable[Index].Alignment,
+ mQNCReservedSpaceTable[Index].RuntimeOrNot,
+ gQNCInitImageHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Report unused PCIe config space as reserved.
+ //
+ if (PcdGet64 (PcdPciExpressSize) < SIZE_256MB) {
+ Status = QNCReserveSpaceInGcd (
+ QNC_RESERVED_ITEM_MEMORYIO,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ (PcdGet64(PcdPciExpressBaseAddress) + PcdGet64(PcdPciExpressSize)),
+ (SIZE_256MB - PcdGet64(PcdPciExpressSize)),
+ 0,
+ FALSE,
+ gQNCInitImageHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
+ Use the platform PCD to initialize devices in the QNC
+
+ @param ImageHandle Handle for the image of this driver.
+ @retval EFI_SUCCESS Initialize successful
+**/
+EFI_STATUS
+InitializeQNCPolicy (
+ )
+{
+ UINT8 RevisionID;
+ UINT32 PciD31F0RegBase; // LPC
+
+ RevisionID = LpcPciCfg8(R_QNC_LPC_REV_ID);
+
+ PciD31F0RegBase = PciDeviceMmBase (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC);
+
+ //
+ // Disable for smbus
+ //
+ if (mQNCDeviceEnables.Bits.Smbus == DXE_DEVICE_DISABLED) {
+ S3MmioAnd32 (PciD31F0RegBase + R_QNC_LPC_SMBUS_BASE, (~B_QNC_LPC_SMBUS_BASE_EN));
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h new file mode 100644 index 0000000000..c6d8592cae --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h @@ -0,0 +1,55 @@ +/** @file
+Header file for QNC Initialization Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 _QNC_INITIALIZATION_DRIVER_H_
+#define _QNC_INITIALIZATION_DRIVER_H_
+
+EFI_STATUS
+QncInitRootPorts (
+ )
+/*++
+
+Routine Description:
+
+ Perform Initialization of the Downstream Root Ports.
+
+Arguments:
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+SetInitRootPortDownstreamS3Item (
+ )
+/*++
+
+Routine Description:
+
+ Set an Init Root Port Downstream devices S3 dispatch item, this function may assert if any error happend
+
+Arguments:
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully
+
+--*/
+;
+
+#endif
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf new file mode 100644 index 0000000000..0bafdd8515 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf @@ -0,0 +1,98 @@ +## @file
+# Component description file for QNCInit driver.
+#
+# QNCInit driver implement QuarkNcSocId related drivers, includes:
+# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
+#
+# This driver mainly do full initialization for the QNC chipet includes:
+# 1. Initialize the PCI Express device.
+# 2. Initialize the PciHostBridge, and allocate the I/O and memory space from GCD service.
+# 3. Initialize the SmmAccess module and install EFI_SMM_ACCESS_PROTOCOL
+# 4. Initialize the LegacyRegion module, install EFI_LEGACY_REGION_PROTOCOL and set below 1M
+# memory attribute from MTRR.
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = QNCInitDxe
+ FILE_GUID = 74D3B506-EE9C-47ed-B749-41261401DA78
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = QNCInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ LegacyRegion.h
+ LegacyRegion.c
+ DxeQNCSmbus.c
+ DxeQNCSmbus.h
+ QNCSmbusExec.c
+ QNCSmbus.h
+ QNCInit.c
+ QNCInit.h
+ CommonHeader.h
+ QNCRootPorts.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ UefiBootServicesTableLib
+ DxeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ MtrrLib
+ IoLib
+ SmbusLib
+ S3IoLib
+ S3BootScriptLib
+ IntelQNCLib
+ QNCAccessLib
+
+[Protocols]
+ gEfiLegacyRegion2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiSmbusHcProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiQncS3SupportProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[FeaturePcd]
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddressFixed
+
+[FixedPcd]
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdIoApicSize
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdHpetSize
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0x0|UINT64|0x60000010 ## PRODUCES
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize ## CONSUMES
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrNum
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPlatformSmbusAddrTable
+
+[Depex]
+ gEfiPlatformPolicyProtocolGuid AND gEfiQncS3SupportProtocolGuid
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c new file mode 100644 index 0000000000..e87d1f45fc --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c @@ -0,0 +1,82 @@ +/** @file
+PciHostBridge driver module, part of QNC module.
+
+Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+#include "QNCInit.h"
+
+UINT32 mS3ParameterRootPortDownstream = 0;
+EFI_QNC_S3_DISPATCH_ITEM mS3DispatchItem = {
+ QncS3ItemTypeInitPcieRootPortDownstream,
+ &mS3ParameterRootPortDownstream
+ };
+
+EFI_STATUS
+QncInitRootPorts (
+ )
+/*++
+
+Routine Description:
+
+ Perform Initialization of the Downstream Root Ports
+
+Arguments:
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_QNC_S3_SUPPORT_PROTOCOL *QncS3Support;
+ VOID *Context;
+ VOID *S3DispatchEntryPoint;
+
+ Status = PciExpressInit ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the QNC S3 Support Protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiQncS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &QncS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the QNC S3 Support Protocol
+ //
+ Status = QncS3Support->SetDispatchItem (
+ QncS3Support,
+ &mS3DispatchItem,
+ &S3DispatchEntryPoint,
+ &Context
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Save the script dispatch item in the Boot Script
+ //
+ Status = S3BootScriptSaveDispatch2 (S3DispatchEntryPoint, Context);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h new file mode 100644 index 0000000000..d0c3e577df --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h @@ -0,0 +1,86 @@ +/** @file
+Common definitons for SMBus PEIM/DXE driver. Smbus PEI and DXE
+modules share the same version of this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 _QNC_SMBUS_H_
+#define _QNC_SMBUS_H_
+
+#include "CommonHeader.h"
+
+//
+// Minimum and maximum length for SMBus bus block protocols defined in SMBus spec 2.0.
+//
+#define MIN_SMBUS_BLOCK_LEN 1
+#define MAX_SMBUS_BLOCK_LEN 32
+#define ADD_LENGTH(SmbusAddress, Length) ((SmbusAddress) + SMBUS_LIB_ADDRESS (0, 0, (Length), FALSE))
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The internal worker function provides a standard way to execute an operation as defined in the
+ System Management Bus (SMBus) Specification. The resulting transaction will be either that the
+ SMBus slave devices accept this transaction or that this function returns with error.
+
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+Execute (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+#endif
diff --git a/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c new file mode 100644 index 0000000000..3fda2a38d5 --- /dev/null +++ b/QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c @@ -0,0 +1,252 @@ +/** @file
+Common code to implement SMBus bus protocols. Smbus PEI and DXE modules
+share the same version of this file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+#include "QNCSmbus.h"
+
+/**
+ Checks the parameter of SmbusExecute().
+
+ This function checks the input parameters of SmbusExecute(). If the input parameters are valid
+ for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
+ error code based on the input SMBus bus protocol.
+
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus
+ protocol.
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+QncSmbusExecCheckParameters (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN RequiredLen;
+
+ //
+ // Set default value to be 2:
+ // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
+ //
+ RequiredLen = 2;
+ Status = EFI_SUCCESS;
+ switch (Operation) {
+ case EfiSmbusQuickRead:
+ case EfiSmbusQuickWrite:
+ if (PecCheck || Command != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ break;
+ case EfiSmbusReceiveByte:
+ case EfiSmbusSendByte:
+ if (Command != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Cascade to check length parameter.
+ //
+ case EfiSmbusReadByte:
+ case EfiSmbusWriteByte:
+ RequiredLen = 1;
+ //
+ // Cascade to check length parameter.
+ //
+ case EfiSmbusReadWord:
+ case EfiSmbusWriteWord:
+ case EfiSmbusProcessCall:
+ if (Buffer == NULL || Length == NULL) {
+ return EFI_INVALID_PARAMETER;
+ } else if (*Length < RequiredLen) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ *Length = RequiredLen;
+ break;
+ case EfiSmbusReadBlock:
+ case EfiSmbusWriteBlock:
+ if ((Buffer == NULL) ||
+ (Length == NULL) ||
+ (*Length < MIN_SMBUS_BLOCK_LEN) ||
+ (*Length > MAX_SMBUS_BLOCK_LEN)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case EfiSmbusBWBRProcessCall:
+ return EFI_UNSUPPORTED;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ return Status;
+}
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The internal worker function provides a standard way to execute an operation as defined in the
+ System Management Bus (SMBus) Specification. The resulting transaction will be either that the
+ SMBus slave devices accept this transaction or that this function returns with error.
+
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ reflected in the Host Status Register bit. Device errors are a
+ result of a transaction collision, illegal command field,
+ unclaimed cycle (host initiated), or bus errors (collisions).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+Execute (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN SmbusAddress;
+ UINTN WorkBufferLen;
+ UINT8 WorkBuffer[MAX_SMBUS_BLOCK_LEN];
+
+ Status = QncSmbusExecCheckParameters (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SmbusAddress = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress, Command, *Length, PecCheck);
+
+ switch (Operation) {
+ case EfiSmbusQuickRead:
+ SmBusQuickRead (SmbusAddress, &Status);
+ break;
+ case EfiSmbusQuickWrite:
+ SmBusQuickWrite (SmbusAddress, &Status);
+ break;
+ case EfiSmbusReceiveByte:
+ *(UINT8 *) Buffer = SmBusReceiveByte (SmbusAddress, &Status);
+ break;
+ case EfiSmbusSendByte:
+ SmBusSendByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
+ break;
+ case EfiSmbusReadByte:
+ *(UINT8 *) Buffer = SmBusReadDataByte (SmbusAddress, &Status);
+ break;
+ case EfiSmbusWriteByte:
+ SmBusWriteDataByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
+ break;
+ case EfiSmbusReadWord:
+ *(UINT16 *) Buffer = SmBusReadDataWord (SmbusAddress, &Status);
+ break;
+ case EfiSmbusWriteWord:
+ SmBusWriteDataWord (SmbusAddress, *(UINT16 *) Buffer, &Status);
+ break;
+ case EfiSmbusProcessCall:
+ *(UINT16 *) Buffer = SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);
+ break;
+ case EfiSmbusReadBlock:
+ WorkBufferLen = SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Read block transaction is complete successfully, and then
+ // check whether the output buffer is large enough.
+ //
+ if (*Length >= WorkBufferLen) {
+ CopyMem (Buffer, WorkBuffer, WorkBufferLen);
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ *Length = WorkBufferLen;
+ }
+ break;
+ case EfiSmbusWriteBlock:
+ SmBusWriteBlock (ADD_LENGTH (SmbusAddress, *Length), Buffer, &Status);
+ break;
+ default:
+ break;
+ }
+
+ return Status;
+}
+
|