Пример #1
0
/**
  Calling this function causes a system-wide initialization. The processors
  are set to their initial state, and pending cycles are not corrupted.

  System reset should not return, if it returns, it means the system does
  not support warm reset.
**/
VOID
EFIAPI
ResetWarm (
  VOID
  )
{
  IoWrite8 (0x64, 0xfe);
  CpuDeadLoop ();
}
Пример #2
0
/**
  Sends an 32-bit value to a POST card.

  Sends the 32-bit value specified by Value to a POST card, and returns Value.  
  Some implementations of this library function may perform I/O operations 
  directly to a POST card device.  Other implementations may send Value to 
  ReportStatusCode(), and the status code reporting mechanism will eventually 
  display the 32-bit value on the status reporting device.
  
  PostCode() must actively prevent recursion.  If PostCode() is called while 
  processing another any other Report Status Code Library function, then 
  PostCode() must return Value immediately.

  @param  Value  The 32-bit value to write to the POST card.

  @return  Value

**/
UINT32
EFIAPI
GluePostCode (
  IN UINT32  Value
  )
{
  IoWrite8 (0x80, (UINT8)(Value));
  return Value;
}
Пример #3
0
UINT8
ReadCmosBank1Byte (
  IN  UINT8                           Index
  )
{
  UINT8                               Data;

  IoWrite8(0x72, Index);
  Data = IoRead8 (0x73);
  return Data;
}
Пример #4
0
/**
  8-bit I/O write operations.

  @param[in] PeiServices  An indirect pointer to the PEI Services Table published
                          by the PEI Foundation.
  @param[in] This         Pointer to local data for the interface.
  @param[in] Address      The physical address of the access.
  @param[in] Data         The data to write.

**/
VOID
EFIAPI
CpuIoWrite8 (
  IN CONST EFI_PEI_SERVICES    **PeiServices,
  IN CONST EFI_PEI_CPU_IO_PPI  *This,
  IN UINT64                    Address,
  IN UINT8                     Data
  )
{
  IoWrite8 ((UINTN)Address, Data);
}
Пример #5
0
VOID
InitializeSio (
  VOID
  )
{
  UINT16          Index;
  UINT16          IndexPort;
  UINT16          DataPort;

  //
  // Super I/O initialization for Winbond WPCN381U
  //
  IndexPort  = WPCN381U_CONFIG_INDEX;
  DataPort   = WPCN381U_CONFIG_DATA;

  //
  // Check for Winbond WPCN381U
  //
  IoWrite8 (IndexPort, WPCN381U_DEV_ID_REGISTER);   // Winbond WPCN381U Device ID register is 0x20

  if (IoRead8 (DataPort) == WPCN381U_CHIP_ID) {   // Winbond WPCN381U Device ID is 0xF4
    //
    // Configure WPCN381U SIO
    //
    for (Index = 0; Index < sizeof (mSioTableWpcn381u) / sizeof (EFI_SIO_TABLE); Index++) {
      IoWrite8 (IndexPort, mSioTableWpcn381u[Index].Register);
      IoWrite8 (DataPort, mSioTableWpcn381u[Index].Value);
    }
  }

  if (IoRead8 (DataPort) == WDCP376_CHIP_ID) {   // Winbond WDCP376 Device ID is 0xF1
    //
    // Configure WDCP376 SIO
    //
    for (Index = 0; Index < sizeof (mSioTableWdcp376) / sizeof (EFI_SIO_TABLE); Index++) {
      IoWrite8 (IndexPort, mSioTableWdcp376[Index].Register);
      IoWrite8 (DataPort, mSioTableWdcp376[Index].Value);
    }
  }
  return;
}
Пример #6
0
/**
  Calling this function causes a system-wide initialization. The processors
  are set to their initial state, and pending cycles are not corrupted.

  System reset should not return, if it returns, it means the system does
  not support warm reset.
**/
VOID
EFIAPI
ResetWarm (
VOID
)
{
  //
  // Reference to QuarkNcSocId BWG
  // Setting bit 1 will generate a warm reset, driving only RSTRDY# low
  //
  IoWrite8 (RST_CNT, B_RST_CNT_WARM_RST);
}
Пример #7
0
/**
  Write I/O registers.

  @param[in]  PeiServices  An indirect pointer to the PEI Services Table
                           published by the PEI Foundation.
  @param[in]  This         Pointer to local data for the interface.
  @param[in]  Width        The width of the access. Enumerated in bytes.
  @param[in]  Address      The physical address of the access.
  @param[in]  Count        The number of accesses to perform.
  @param[in]  Buffer       A pointer to the buffer of data.

  @retval EFI_SUCCESS            The function completed successfully.
  @retval EFI_INVALID_PARAMETER  Width is invalid for this EFI system.
  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
  @retval EFI_UNSUPPORTED        The address range specified by Address, Width, 
                                 and Count is not valid for this EFI system.

**/
EFI_STATUS
EFIAPI
CpuIoServiceWrite (
  IN CONST EFI_PEI_SERVICES    **PeiServices,
  IN CONST EFI_PEI_CPU_IO_PPI  *This,
  IN EFI_PEI_CPU_IO_PPI_WIDTH  Width,
  IN UINT64                    Address,
  IN UINTN                     Count,
  IN VOID                      *Buffer
  )
{
  EFI_STATUS                Status;
  UINT8                     InStride;
  UINT8                     OutStride;
  EFI_PEI_CPU_IO_PPI_WIDTH  OperationWidth;
  BOOLEAN                   Aligned;
  UINT8                     *Uint8Buffer;

  //
  // Make sure the parameters are valid
  //
  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select loop based on the width of the transfer
  //
  InStride = mInStride[Width];
  OutStride = mOutStride[Width];
  OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
  Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
    if (OperationWidth == EfiPeiCpuIoWidthUint8) {
      IoWrite8 ((UINTN)Address, *Uint8Buffer);
    } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
      if (Aligned) {
        IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
      } else {
        IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
      }
    } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
      if (Aligned) {
        IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
      } else {
        IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
      }
    }
  }
  
  return EFI_SUCCESS;
}
Пример #8
0
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);
}
Пример #9
0
/**
  I/O work flow of outing 8042 data.

  @param Data    Data value

  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042Data (
  IN UINT8                                Data
  )
{
  EFI_STATUS  Status;
  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  IoWrite8 (KBC_DATA_PORT, Data);
  return WaitInputEmpty (TIMEOUT);
}
Пример #10
0
/**
  Calling this function causes a system-wide initialization. The processors
  are set to their initial state, and pending cycles are not corrupted.

  System reset should not return, if it returns, it means the system does
  not support warm reset.
**/
VOID
EFIAPI
ResetWarm (
  VOID
  )
{
	EFI_HOB_GUID_TYPE  *GuidHob;
	ACPI_BOARD_INFO    *pAcpiBoardInfo;	
		
	//
	// Find the acpi board information guid hob
	//
	GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid);
	ASSERT (GuidHob != NULL);
  pAcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob); 
	
  IoWrite8 ((UINTN)pAcpiBoardInfo->ResetRegAddress, pAcpiBoardInfo->ResetValue);
  CpuDeadLoop ();
}
Пример #11
0
/**
  Write I/O registers.

  The I/O operations are carried out exactly as requested. The caller is responsible 
  for satisfying any alignment and I/O width restrictions that a PI System on a 
  platform might require. For example on some platforms, width requests of 
  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will 
  be handled by the driver.
  
  If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, 
  or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for 
  each of the Count operations that is performed.
  
  If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, 
  EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is 
  incremented for each of the Count operations that is performed. The read or 
  write operation is performed Count times on the same Address.
  
  If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, 
  EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is 
  incremented for each of the Count operations that is performed. The read or 
  write operation is performed Count times from the first element of Buffer.
  
  @param[in]  This     A pointer to the EFI_CPU_IO2_PROTOCOL instance.
  @param[in]  Width    Signifies the width of the I/O or Memory operation.
  @param[in]  Address  The base address of the I/O operation. 
  @param[in]  Count    The number of I/O operations to perform. The number of 
                       bytes moved is Width size * Count, starting at Address.
  @param[in]  Buffer   For read operations, the destination buffer to store the results.
                       For write operations, the source buffer from which to write data.

  @retval EFI_SUCCESS            The data was read from or written to the PI system.
  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
  @retval EFI_UNSUPPORTED        The address range specified by Address, Width, 
                                 and Count is not valid for this PI system.
                                 
**/
EFI_STATUS
EFIAPI
CpuIoServiceWrite (
  IN EFI_CPU_IO2_PROTOCOL       *This,
  IN EFI_CPU_IO_PROTOCOL_WIDTH  Width,
  IN UINT64                     Address,
  IN UINTN                      Count,
  IN VOID                       *Buffer
  )
{
  EFI_STATUS                 Status;
  UINT8                      InStride;
  UINT8                      OutStride;
  EFI_CPU_IO_PROTOCOL_WIDTH  OperationWidth;
  UINT8                      *Uint8Buffer;

  //
  // Make sure the parameters are valid
  //
  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select loop based on the width of the transfer
  //
  InStride = mInStride[Width];
  OutStride = mOutStride[Width];
  OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03);
  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
    if (OperationWidth == EfiCpuIoWidthUint8) {
      IoWrite8 ((UINTN)Address, *Uint8Buffer);
    } else if (OperationWidth == EfiCpuIoWidthUint16) {
      IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
    } else if (OperationWidth == EfiCpuIoWidthUint32) {
      IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
    }
  }
  
  return EFI_SUCCESS;
}
Пример #12
0
/**

  This function is IO handler for reset.

  @param Index CPU index
  @param Port  Reset IO port address
  @param Data  Reset IO port data

**/
VOID
IoResetHandler (
  IN UINT32  Index,
  IN UINT16  Port,
  IN UINT8   Data
  )
{
  DEBUG ((EFI_D_INFO, "(FRM) !!!IoResetHandler!!!\n"));

  FrmTeardownBsp (Index);
  AsmWbinvd ();

  //
  // Work-around for CTRL+ALT+DEL, it will pass 0x2.
  //
  Data = Data | 0x6;
  IoWrite8 (Port, Data);

  CpuDeadLoop ();

  return ;
}
Пример #13
0
BOOLEAN
IsRtcUipAlwaysSet (
  IN CONST EFI_PEI_SERVICES       **PeiServices
  )
{

  EFI_PEI_STALL_PPI *StallPpi;
  UINTN             Count;

  (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);

  for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
    if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) {
      return FALSE;
    }

    StallPpi->Stall (PeiServices, StallPpi, 3000);
  }

  return TRUE;
}
Пример #14
0
/**
  Write I/O registers.

  The I/O operations are carried out exactly as requested.  The caller is 
  responsible for any alignment and I/O width issues that the bus, device, 
  platform, or type of I/O might require.

  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
  @param[in]  Width    Signifies the width of the I/O operations.
  @param[in]  Address  The base address of the I/O operations.  The caller is 
                       responsible for aligning the Address if required. 
  @param[in]  Count    The number of I/O operations to perform.
  @param[in]  Buffer   For read operations, the destination buffer to store 
                       the results.  For write operations, the source buffer 
                       from which to write data.

  @retval EFI_SUCCESS            The data was read from or written to the device.
  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a 
                                 lack of resources

**/
EFI_STATUS
EFIAPI
CpuIoServiceWrite (
  IN CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
  IN EFI_SMM_IO_WIDTH                Width,
  IN UINT64                          Address,
  IN UINTN                           Count,
  IN VOID                            *Buffer
  )
{
  EFI_STATUS  Status;
  UINT8       Stride;
  UINT8       *Uint8Buffer;

  //
  // Make sure the parameters are valid
  //
  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select loop based on the width of the transfer
  //
  Stride = mStride[Width];
  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
    if (Width == SMM_IO_UINT8) {
      IoWrite8 ((UINTN)Address, *Uint8Buffer);
    } else if (Width == SMM_IO_UINT16) {
      IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
    } else if (Width == SMM_IO_UINT32) {
      IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
    }
  }
  
  return EFI_SUCCESS;
}
Пример #15
0
/**
  Prints a debug message to the debug output device if the specified error level is enabled.

  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
  GetDebugPrintErrorLevel (), then print the message specified by Format and the
  associated variable argument list to the debug output device.

  If Format is NULL, then ASSERT().

  @param  ErrorLevel  The error level of the debug message.
  @param  Format      Format string for the debug message to print.
  @param  ...         Variable argument list whose contents are accessed
                      based on the format string specified by Format.

**/
VOID
EFIAPI
DebugPrint (
  IN  UINTN        ErrorLevel,
  IN  CONST CHAR8  *Format,
  ...
  )
{
  CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];
  VA_LIST  Marker;
  UINT8    *Ptr;

  //
  // If Format is NULL, then ASSERT().
  //
  ASSERT (Format != NULL);

  //
  // Check driver debug mask value and global mask
  //
  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
    return;
  }

  //
  // Convert the DEBUG() message to an ASCII String
  //
  VA_START (Marker, Format);
  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
  VA_END (Marker);

  //
  // Send the print string to the debug I/O port
  //
  for (Ptr = (UINT8 *) Buffer; *Ptr; Ptr++) {
    IoWrite8 (PcdGet16(PcdDebugIoPort), *Ptr);
  }
}
Пример #16
0
/**
  Calling this function causes the system to enter a power state for capsule
  update.

  Reset update should not return, if it returns, it means the system does
  not support capsule update.

**/
VOID
EFIAPI
EnterS3WithImmediateWake (
VOID
)
{
  UINT8     Data8;
  UINT16    Data16;
  UINT32    Data32;
  UINTN     Eflags;
  UINTN     RegCr0;
  EFI_TIME  EfiTime;
  UINT32    SmiEnSave;

  Eflags  = AsmReadEflags ();
  if ( (Eflags & 0x200) ) {
     DisableInterrupts ();
  }

  //
  //  Write all cache data to memory because processor will lost power
  //
  AsmWbinvd();
  RegCr0 = AsmReadCr0();
  AsmWriteCr0 (RegCr0 | 0x060000000);

  SmiEnSave = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, (SmiEnSave & ~SMI_EN));

  //
  // Pogram RTC alarm for immediate WAKE
  //

  //
  // Disable SMI sources
  //
  IoWrite16 (PcdGet16 (PcdGpe0blkIoBaseAddress) + R_QNC_GPE0BLK_SMIE, 0);

  //
  // Disable RTC alarm interrupt
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 & ~BIT5));

  //
  // Clear RTC alarm if already set
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);              // Read clears alarm status

  //
  // Disable all WAKE events
  //
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, B_QNC_PM1BLK_PM1E_PWAKED);

  //
  // Clear all WAKE status bits
  //
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S, B_QNC_PM1BLK_PM1S_ALL);

  //
  // Avoid RTC rollover
  //
  do {
    WaitForRTCUpdate();
    IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
    EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);
  } while (EfiTime.Second > PLATFORM_RTC_ROLLOVER_LIMIT);

  //
  // Read RTC time
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS);
  EfiTime.Hour = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES);
  EfiTime.Minute = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
  EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);

  //
  // Set RTC alarm
  //

  //
  // Add PLATFORM_WAKE_SECONDS_BUFFER to current EfiTime.Second
  // The maths is to allow for the fact we are adding to a BCD number and require the answer to be BCD (EfiTime.Second)
  //
  if ((BCD_BASE - (EfiTime.Second & 0x0F)) <= PLATFORM_WAKE_SECONDS_BUFFER) {
    Data8 = (((EfiTime.Second & 0xF0) + 0x10) + (PLATFORM_WAKE_SECONDS_BUFFER - (BCD_BASE - (EfiTime.Second & 0x0F))));
  } else {
    Data8 = EfiTime.Second + PLATFORM_WAKE_SECONDS_BUFFER;
  }

  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Hour);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Minute);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, Data8);

  //
  // Enable RTC alarm interrupt
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 | BIT5));

  //
  // Enable RTC alarm as WAKE event
  //
  Data16 = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E);
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, (Data16 | B_QNC_PM1BLK_PM1E_RTC));

  //
  // Enter S3
  //
  Data32 = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
  Data32  = (UINT32) ((Data32 & 0xffffc3fe) | V_S3 | B_QNC_PM1BLK_PM1C_SCIEN);
  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);
  Data32 = Data32 | B_QNC_PM1BLK_PM1C_SLPEN;
  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);

  //
  // Enable Interrupt if it's enabled before
  //
  if ( (Eflags & 0x200) ) {
     EnableInterrupts ();
  }
}
Пример #17
0
void Turn_On_5V_DAUL_USBKB_Power()
{
//Switch +5V_DAUL_USBKB to standby power
	UINT8 Reg = 0;

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x87);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0x87);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x07);
	IoWrite8(NCT6791D_CONFIG_DATA,  0x07);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x30);
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg |= BIT1;					//Active GPIO7 Group
	IoWrite8(NCT6791D_CONFIG_DATA,  Reg);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE0);
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg &= ~BIT2;					//Set GPIO72 to output
	IoWrite8(NCT6791D_CONFIG_DATA,  Reg);	

	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg |= BIT2;					//Set GPIO72 to output High
	IoWrite8(NCT6791D_CONFIG_DATA,  Reg);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x07);
	IoWrite8(NCT6791D_CONFIG_DATA,  0x0F);	

	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE6);
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg &= ~BIT2;					//Set GPIO72 to Push-Pull
	IoWrite8(NCT6791D_CONFIG_DATA,  Reg);	

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x1D);		//SET GP54 TO PWROK
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg &= ~(BIT1+BIT2+BIT3);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0x1D);
	IoWrite8(NCT6791D_CONFIG_DATA, Reg|(BIT3+BIT2));

	IoWrite8(NCT6791D_CONFIG_INDEX, 0xaa);
}
Пример #18
0
void Turn_On_KB_Power_ON()
{
	UINT8 Reg;
	IoWrite8(NCT6791D_CONFIG_INDEX, 0x87);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0x87);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x07);
	IoWrite8(NCT6791D_CONFIG_DATA,  0x0A);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0x30);
	Reg = IoRead8(NCT6791D_CONFIG_DATA);
	Reg |= 0x01;					
	IoWrite8(NCT6791D_CONFIG_DATA,  Reg);


	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE0);
	Reg=IoRead8(NCT6791D_CONFIG_DATA);
	Reg=Reg |  (BIT(6) + BIT(5) + BIT(4) + BIT(1) + BIT(0));
	Reg=Reg & ~BIT(7);
	printf("LDN A index 0xE0 is %x\n",Reg);
	IoWrite8(NCT6791D_CONFIG_DATA, Reg);

	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE6);
	Reg=IoRead8(NCT6791D_CONFIG_DATA);
	Reg=Reg | BIT(7);
	printf("LDN A index 0xE6 is %x\n",Reg);
	IoWrite8(NCT6791D_CONFIG_DATA, Reg);


	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE4);
	Reg=IoRead8(NCT6791D_CONFIG_DATA);
	Reg = Reg | 0x10;
	IoWrite8(NCT6791D_CONFIG_DATA, Reg);

	//E
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);					
	IoWrite8(NCT6791D_CONFIG_DATA, 0x00);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x24);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x01);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0xF0);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x02);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x24);
	//R
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x03);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x2D);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x04);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0xF0);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x05);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x2D);
	//A
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x06);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x1C);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x07);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0xF0);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x08);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x1C);
	//L
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x09);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x4B);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x0A);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0xF0);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x0B);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x4B);
	//C
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x0C);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x21);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);						
	IoWrite8(NCT6791D_CONFIG_DATA, 0x0D);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0xF0);
	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE1);						
	IoWrite8(NCT6791D_CONFIG_DATA, 0x0E);
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xE2);
	IoWrite8(NCT6791D_CONFIG_DATA, 0x21);
	
	


	
	IoWrite8(NCT6791D_CONFIG_INDEX, 0xaa);
}
Пример #19
0
UINT8 smb_read_byte(UINT32 base, UINT8 adr, UINT8 cmd)
{
  //   INTN l1, h1, l2, h2;
  UINT64 t, t1, t2;
    
  if (smbIntel) {
      IoWrite8(base + SMBHSTSTS, 0x1f);				// reset SMBus Controller
      IoWrite8(base + SMBHSTDAT, 0xff);
	
      t1 = AsmReadTsc(); //rdtsc(l1, h1);
      while ( IoRead8(base + SMBHSTSTS) & 0x01)    // wait until read
      {
          t2 = AsmReadTsc(); //rdtsc(l2, h2);
          t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0);
          if (t > 5)
              return 0xFF;                  // break
      }
	
      IoWrite8(base + SMBHSTCMD, cmd);
      IoWrite8(base + SMBHSTADD, (adr << 1) | 0x01 );
      IoWrite8(base + SMBHSTCNT, 0x48 );
	
      t1 = AsmReadTsc();
	
      while (!( IoRead8(base + SMBHSTSTS) & 0x02))		// wait til command finished
      {
          t2 = AsmReadTsc();
          t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0);
          if (t > 5)
              break;									// break after 5ms
      }
      return IoRead8(base + SMBHSTDAT);
  }
  else {
      IoWrite8(base + SMBHSTSTS_NV, 0x1f);			// reset SMBus Controller
      IoWrite8(base + SMBHSTDAT_NV, 0xff);
    
      t1 = AsmReadTsc(); //rdtsc(l1, h1);
      while ( IoRead8(base + SMBHSTSTS_NV) & 0x01)    // wait until read
      {
          t2 = AsmReadTsc(); //rdtsc(l2, h2);
          t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0);
          if (t > 5)
              return 0xFF;                  // break
      }
    
      IoWrite8(base + SMBHSTSTS_NV, 0x00); // clear status register
      IoWrite8(base + SMBHSTCMD_NV, cmd);
      IoWrite8(base + SMBHSTADD_NV, (adr << 1) | 0x01 );
      IoWrite8(base + SMBHPRTCL_NV, 0x07 );
      t1 = AsmReadTsc();
    
      while (!( IoRead8(base + SMBHSTSTS_NV) & 0x9F))		// wait till command finished
      {
          t2 = AsmReadTsc();
          t = DivU64x64Remainder((t2 - t1), DivU64x32(gCPUStructure.TSCFrequency, 1000), 0);
          if (t > 5)
              break; // break after 5ms
      }
      return IoRead8(base + SMBHSTDAT_NV);
    }
}
Пример #20
0
EFI_STATUS
EFIAPI
PeiInitPlatform (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  UINTN                            SmbusRegBase;
  EFI_PLATFORM_INFO_HOB            PlatformInfo;
  EFI_STATUS                       Status= EFI_SUCCESS;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable = NULL;
  UINTN                            VariableSize;
  SYSTEM_CONFIGURATION             SystemConfiguration;
  UINT32                           GGC = 0;

  EFI_PEI_PPI_DESCRIPTOR          *mVlvMmioPolicyPpiDesc;
  VLV_MMIO_POLICY_PPI             *mVlvMmioPolicyPpi;

  ZeroMem (&PlatformInfo, sizeof(PlatformInfo));

  Status =  InstallMonoStatusCode(FileHandle, PeiServices);
  ASSERT_EFI_ERROR (Status);


  //
  // Initialize Stall PPIs
  //
  Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
  ASSERT_EFI_ERROR (Status);

  Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);
  ASSERT_EFI_ERROR (Status);
  SmbusRegBase = PchPciDeviceMmBase (
                   DEFAULT_PCI_BUS_NUMBER_PCH,
                   PCI_DEVICE_NUMBER_PCH_SMBUS,
                   PCI_FUNCTION_NUMBER_PCH_SMBUS
                   );
  //
  // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
  //
  MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);

  MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);

  PchBaseInit();

  //
  //Todo: confirm if we need program 8254
  //
  // Setting 8254
  // Program timer 1 as refresh timer
  //
  IoWrite8 (0x43, 0x54);
  IoWrite8 (0x41, 0x12);

  //
  // RTC power failure handling
  //
  RtcPowerFailureHandler (PeiServices);


  PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;

  VariableSize = sizeof (SYSTEM_CONFIGURATION);
  ZeroMem (&SystemConfiguration, VariableSize);

  //
  // Obtain variable services
  //
  Status = (*PeiServices)->LocatePpi(
                             PeiServices,
                             &gEfiPeiReadOnlyVariable2PpiGuid,
                             0,
                             NULL,
                             (void **)&Variable
                             );
  ASSERT_EFI_ERROR(Status);
  Status = Variable->GetVariable (
                       Variable,
                       L"Setup",
                       &gEfiSetupVariableGuid,
                       NULL,
                       &VariableSize,
                       &SystemConfiguration
					   );
  if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
    //The setup variable is corrupted
    VariableSize = sizeof(SYSTEM_CONFIGURATION);
    Status = Variable->GetVariable(
              Variable,
              L"SetupRecovery",
              &gEfiSetupVariableGuid,
              NULL,
              &VariableSize,
              &SystemConfiguration
              );
    ASSERT_EFI_ERROR (Status);
  }
  
  if (EFI_ERROR (Status)) {
    GGC = ((2 << 3) | 0x200);
    PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
    GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
    DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
  } else {
    if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
Пример #21
0
EFI_STATUS
SxSleepEntryCallBack (
  IN  EFI_HANDLE                    DispatchHandle,
  IN  CONST VOID                    *DispatchContext,
  IN  OUT VOID                      *CommBuffer,
  IN  OUT UINTN                     *CommBufferSize
  )
/*++

Routine Description:

  Callback function entry for Sx sleep state.

Arguments:

  DispatchHandle   -  The handle of this callback, obtained when registering.
  DispatchContext  -  The predefined context which contained sleep type and phase.

Returns:

  EFI_SUCCESS            -  Operation successfully performed.
  EFI_INVALID_PARAMETER  -  Invalid parameter passed in.

--*/
{
  EFI_STATUS  Status;
  UINT8       Data8;
  UINT16      Data16;
  UINT32      Data32;

  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeS3SuspendStart));

  //
  // Reget QNC power mgmr regs base in case of OS changing it at runtime
  //
  Status  = GetAllQncPmBase (gSmst);

  //
  // Clear RTC Alarm (if set)
  //
  Data8 = RTC_ADDRESS_REGISTER_C;
  IoWrite8 (R_IOPORT_CMOS_STANDARD_INDEX, Data8);
  Data8 = IoRead8 (R_IOPORT_CMOS_STANDARD_DATA);

  //
  // Clear all ACPI status bits
  //
  Data32 = B_QNC_GPE0BLK_GPE0S_ALL;
  Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0S, 1, &Data32 );
  Data16 = B_QNC_PM1BLK_PM1S_ALL;
  Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1S, 1, &Data16 );

  //
  // Handling S1 - setting appropriate wake bits in GPE0_EN
  //
  if ((DispatchHandle == mAcpiSmm.S1SleepEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS1)) {
    //
    // Enable bit13 (EGPE), 14 (GPIO) ,17 (PCIE) in GPE0_EN
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );

    //
    // Enable bit10 (RTC) in PM1E
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );

    return EFI_SUCCESS;
  }

  //
  // Handling S4, S5 and WOL - setting appropriate wake bits in GPE0_EN
  //
  if (((DispatchHandle == mAcpiSmm.S4SleepEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS4)) ||
      ((DispatchHandle == mAcpiSmm.S5SoftOffEntryHandle) && (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type == SxS5))
     ) {
    //
    // Enable bit13 (EGPE), 14 (GPIO) ,17 (PCIE) in GPE0_EN
    // Enable the WOL bits in GPE0_EN reg here for PME
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );

    //
    // Enable bit10 (RTC) in PM1E
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );

  } else {

    if ((DispatchHandle != mAcpiSmm.S3SleepEntryHandle) || (((EFI_SMM_SX_REGISTER_CONTEXT *)DispatchContext)->Type != SxS3)) {
      return EFI_INVALID_PARAMETER;
    }

    Status  = SaveRuntimeScriptTable (gSmst);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Enable bit13 (EGPE), 14 (GPIO), 17 (PCIE) in GPE0_EN
    // Enable the WOL bits in GPE0_EN reg here for PME
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );
    Data32 |= (B_QNC_GPE0BLK_GPE0E_EGPE | B_QNC_GPE0BLK_GPE0E_GPIO | B_QNC_GPE0BLK_GPE0E_PCIE);
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT32, mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_GPE0E, 1, &Data32 );

    //
    // Enable bit10 (RTC) in PM1E
    //
    Status = gSmst->SmmIo.Io.Read( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
    Data16 |= B_QNC_PM1BLK_PM1E_RTC;
    Status = gSmst->SmmIo.Io.Write( &gSmst->SmmIo, SMM_IO_UINT16, mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1E, 1, &Data16 );
  }

  //
  // When entering a power-managed state like S3,
  // PERST# must be asserted in advance of power-off.
  //
  PlatformPERSTAssert (mPlatformType);

  return EFI_SUCCESS;
}
Пример #22
0
/**
  Write I/O registers.

  @param[in]  PeiServices  An indirect pointer to the PEI Services Table
                           published by the PEI Foundation.
  @param[in]  This         Pointer to local data for the interface.
  @param[in]  Width        The width of the access. Enumerated in bytes.
  @param[in]  Address      The physical address of the access.
  @param[in]  Count        The number of accesses to perform.
  @param[in]  Buffer       A pointer to the buffer of data.

  @retval EFI_SUCCESS            The function completed successfully.
  @retval EFI_INVALID_PARAMETER  Width is invalid for this EFI system.
  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
                                 and Count is not valid for this EFI system.

**/
EFI_STATUS
EFIAPI
CpuIoServiceWrite (
  IN CONST EFI_PEI_SERVICES    **PeiServices,
  IN CONST EFI_PEI_CPU_IO_PPI  *This,
  IN EFI_PEI_CPU_IO_PPI_WIDTH  Width,
  IN UINT64                    Address,
  IN UINTN                     Count,
  IN VOID                      *Buffer
  )
{
  EFI_STATUS                Status;
  UINT8                     InStride;
  UINT8                     OutStride;
  EFI_PEI_CPU_IO_PPI_WIDTH  OperationWidth;
  BOOLEAN                   Aligned;
  UINT8                     *Uint8Buffer;

  //
  // Make sure the parameters are valid
  //
  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select loop based on the width of the transfer
  //
  InStride = mInStride[Width];
  OutStride = mOutStride[Width];
  OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);

  //
  // Fifo operations supported for (mInStride[Width] == 0)
  //
  if (InStride == 0) {
    switch (OperationWidth) {
    case EfiPeiCpuIoWidthUint8:
      IoWriteFifo8 ((UINTN)Address, Count, Buffer);
      return EFI_SUCCESS;
    case EfiPeiCpuIoWidthUint16:
      IoWriteFifo16 ((UINTN)Address, Count, Buffer);
      return EFI_SUCCESS;
    case EfiPeiCpuIoWidthUint32:
      IoWriteFifo32 ((UINTN)Address, Count, Buffer);
      return EFI_SUCCESS;
    default:
      //
      // The CpuIoCheckParameter call above will ensure that this
      // path is not taken.
      //
      ASSERT (FALSE);
      break;
    }
  }

  Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
    if (OperationWidth == EfiPeiCpuIoWidthUint8) {
      IoWrite8 ((UINTN)Address, *Uint8Buffer);
    } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
      if (Aligned) {
        IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
      } else {
        IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
      }
    } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
      if (Aligned) {
        IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
      } else {
        IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
      }
    }
  }

  return EFI_SUCCESS;
}
Пример #23
0
/**
  I/O work flow of outing 8042 Aux command.

  @param Command Aux I/O command
  @param Resend  Whether need resend the Aux command.

  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042AuxCommand (
  IN UINT8                                Command,
  IN BOOLEAN                              Resend
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send write to auxiliary device command
  //
  IoWrite8 (KBC_CMD_STS_PORT, WRITE_AUX_DEV);

  Status = WaitInputEmpty (TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send auxiliary device command
  //
  IoWrite8 (KBC_DATA_PORT, Command);

  //
  // Read return code
  //
  Status = In8042AuxData (&Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Data == PS2_ACK) {
    //
    // Receive mouse acknowledge, command send success
    //
    return EFI_SUCCESS;

  } else if (Resend) {
    //
    // Resend fail
    //
    return EFI_DEVICE_ERROR;

  } else if (Data == PS2_RESEND) {
    //
    // Resend command
    //
    Status = Out8042AuxCommand (Command, TRUE);
    if (EFI_ERROR (Status)) {
      return Status;
    }

  } else {
    //
    // Invalid return code
    //
    return EFI_DEVICE_ERROR;

  }

  return EFI_SUCCESS;
}
Пример #24
0
VOID
EnableS5WakeOnRtc()
{
  UINT8             CmosData;
  UINTN             i;
  EFI_STATUS        Status;
  UINTN             VarSize;

  //
  // make sure EFI_SMM_VARIABLE_PROTOCOL is available
  //
  if (!mSmmVariable) {
    return;
  }

  VarSize = sizeof(SYSTEM_CONFIGURATION);

  //
  // read the variable into the buffer
  //
  Status = mSmmVariable->SmmGetVariable(
                           L"Setup",
                           &gEfiSetupVariableGuid,
                           NULL,
                           &VarSize,
                           &mSystemConfiguration
                           );
  if (EFI_ERROR(Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
    //The setup variable is corrupted
    VarSize = sizeof(SYSTEM_CONFIGURATION);
    Status = mSmmVariable->SmmGetVariable(
              L"SetupRecovery",
              &gEfiSetupVariableGuid,
              NULL,
              &VarSize,
              &mSystemConfiguration
              );
    ASSERT_EFI_ERROR (Status);
  }

  if (!mSystemConfiguration.WakeOnRtcS5) {
    return;
  }
  mWakeupDay = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupDate);
  mWakeupHour = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeHour);
  mWakeupMinute = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeMinute);
  mWakeupSecond = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeSecond);

  //
  // Check RTC alarm interrupt is enabled.  If enabled, someone already
  // grabbed RTC alarm.  Just return.
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  if(IoRead8(PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE){
    return;
  }

  //
  // Set Date
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
  CmosData = IoRead8(PCAT_RTC_DATA_REGISTER);
  CmosData &= ~(B_RTC_DATE_ALARM_MASK);
  CmosData |= mWakeupDay ;
  for(i = 0 ; i < 0xffff ; i++){
    IoWrite8(PCAT_RTC_DATA_REGISTER, CmosData);
    SmmStall(1);
    if(((CmosData = IoRead8(PCAT_RTC_DATA_REGISTER)) & B_RTC_DATE_ALARM_MASK)
         == mWakeupDay){
      break;
    }
  }

  //
  // Set Second
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECOND_ALARM);
  for(i = 0 ; i < 0xffff ; i++){
    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupSecond);
    SmmStall(1);
    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupSecond){
      break;
    }
  }

  //
  // Set Minute
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTE_ALARM);
  for(i = 0 ; i < 0xffff ; i++){
    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupMinute);
    SmmStall(1);
    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupMinute){
      break;
    }
  }

  //
  // Set Hour
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM);
  for(i = 0 ; i < 0xffff ; i++){
    IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupHour);
    SmmStall(1);
    if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupHour){
      break;
    }
  }

  //
  // Wait for UIP to arm RTC alarm
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
  while (IoRead8(PCAT_RTC_DATA_REGISTER) & 0x80);

  //
  // Read RTC register 0C to clear pending RTC interrupts
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
  IoRead8(PCAT_RTC_DATA_REGISTER);

  //
  // Enable RTC Alarm Interrupt
  //
  IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  IoWrite8(PCAT_RTC_DATA_REGISTER, IoRead8(PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE);

  //
  // Clear ICH RTC Status
  //
  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC);

  //
  // Enable ICH RTC event
  //
  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
              (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC));
}
Пример #25
0
/**

  This function is IO instruction handler.

  @param Index CPU index

**/
VOID
IoHandler (
  IN UINT32 Index
  )
{
  VM_EXIT_QUALIFICATION   Qualification;
  UINT16                  Port;
  UINTN                   *DataPtr;
  IO_WRITE_HANDLER_ITEM   *IoWriteHandler;
  IO_READ_HANDLER_ITEM    *IoReadHandler;
  UINT32                  Action;
  UINT32                  Value;
  UINTN                   LinearAddr;

  Qualification.UintN = VmReadN (VMCS_N_RO_EXIT_QUALIFICATION_INDEX);

  Port = (UINT16)Qualification.IoInstruction.PortNum;
  DataPtr = (UINTN *)&mGuestContextCommon.GuestContextPerCpu[Index].Register.Rax;

  if (Qualification.IoInstruction.Rep) {
    UINT64 RcxMask;

    RcxMask = 0xFFFFFFFFFFFFFFFFull;
    if ((mGuestContextCommon.GuestContextPerCpu[Index].EFER & IA32_EFER_MSR_MLA) == 0) {
      RcxMask = 0xFFFFFFFFull;
    }
    if ((mGuestContextCommon.GuestContextPerCpu[Index].Register.Rcx & RcxMask) == 0) {
      // Skip
      VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN(VMCS_N_GUEST_RIP_INDEX) + VmRead32(VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
      return ;
    }
  }

  if (Port == 0xB2) {
    DEBUG ((EFI_D_INFO, "(FRM) !!! SmiCmd(0xb2) - 0x%02x !!!\n", (UINT8)*DataPtr));
  }

  if ((mHostContextCommon.ResetIoPortBaseAddress != 0) && (Port == mHostContextCommon.ResetIoPortBaseAddress) && (Qualification.IoInstruction.Direction == 0)) {
    IoResetHandler (Index, Port, (UINT8)*DataPtr);
  } else if ((Port == mHostContextCommon.AcpiPmControlIoPortBaseAddress) && (Qualification.IoInstruction.Direction == 0)) {
    IoAcpiHandler (Index, Port, (UINT32)*DataPtr);
  }

  if (Qualification.IoInstruction.String) {
    LinearAddr = VmReadN (VMCS_N_RO_GUEST_LINEAR_ADDR_INDEX);
    if (VmReadN (VMCS_N_GUEST_CR0_INDEX) & CR0_PG) {
      DataPtr = (UINTN *)(UINTN)GuestVirtualToGuestPhysical (Index, LinearAddr);
    } else {
      DataPtr = (UINTN *)LinearAddr;
    }

    if (VmReadN (VMCS_N_GUEST_RFLAGS_INDEX) & RFLAGS_DF) {
      if (Qualification.IoInstruction.Direction) {
        mGuestContextCommon.GuestContextPerCpu[Index].Register.Rdi -= Qualification.IoInstruction.Size + 1;
      } else {
        mGuestContextCommon.GuestContextPerCpu[Index].Register.Rsi -= Qualification.IoInstruction.Size + 1;
      }
    } else {
      if (Qualification.IoInstruction.Direction) {
        mGuestContextCommon.GuestContextPerCpu[Index].Register.Rdi += Qualification.IoInstruction.Size + 1;
      } else {
        mGuestContextCommon.GuestContextPerCpu[Index].Register.Rsi += Qualification.IoInstruction.Size + 1;
      }
    }
  }

  if (Qualification.IoInstruction.Direction) { // IN
    IoReadHandler = FindIoReadHandler (Port, Qualification.IoInstruction.Size + 1);
    if (IoReadHandler != NULL) {
      Action = IO_ACTION_NO_ACTION;
      Value = 0;
      IoReadHandler->Handler (IoReadHandler->Context, Port, &Value, &Action);
      if (Action == IO_ACTION_NO_ACTION) {
        switch (Qualification.IoInstruction.Size) {
        case 0:
          *(UINT8 *)DataPtr = (UINT8)Value;
          goto Ret;
          break;
        case 1:
          *(UINT16 *)DataPtr = (UINT16)Value;
          goto Ret;
          break;
        case 3:
          *(UINT32 *)DataPtr = Value;
          goto Ret;
          break;
        default:
          break;
        }
        goto Ret;
      } else {
        // Passthrough
      }
    }
    switch (Qualification.IoInstruction.Size) {
    case 0:
      *(UINT8 *)DataPtr = IoRead8 (Port);
      goto Ret;
      break;
    case 1:
      *(UINT16 *)DataPtr = IoRead16 (Port);
      goto Ret;
      break;
    case 3:
      *(UINT32 *)DataPtr = IoRead32 (Port);
      goto Ret;
      break;
    default:
      break;
    }
  } else { // OUT
    IoWriteHandler = FindIoWriteHandler (Port, Qualification.IoInstruction.Size + 1);
    if (IoWriteHandler != NULL) {
      Action = IO_ACTION_NO_ACTION;
      Value = (UINT32)*DataPtr;
      IoWriteHandler->Handler (IoWriteHandler->Context, Port, Value, &Action);
      if (Action == IO_ACTION_NO_ACTION) {
        goto Ret;
      } else {
        // Passthrough
      }
    }
    switch (Qualification.IoInstruction.Size) {
    case 0:
      IoWrite8 (Port, (UINT8)*DataPtr);
      goto Ret;
      break;
    case 1:
      IoWrite16 (Port, (UINT16)*DataPtr);
      goto Ret;
      break;
    case 3:
      IoWrite32 (Port, (UINT32)*DataPtr);
      goto Ret;
      break;
    default:
      break;
    }
  }

  DEBUG ((EFI_D_ERROR, "(FRM) !!!IoHandler!!!\n"));
  DumpVmcsAllField ();

  CpuDeadLoop ();

Ret:
  if (Qualification.IoInstruction.Rep) {
    // replay
    mGuestContextCommon.GuestContextPerCpu[Index].Register.Rcx --;
    return ;
  }

  VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN(VMCS_N_GUEST_RIP_INDEX) + VmRead32(VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
  return ;
}
Пример #26
0
EFI_STATUS
EnableAcpiCallback (
  IN  EFI_HANDLE                    DispatchHandle,
  IN  CONST VOID                    *DispatchContext,
  IN  OUT VOID                      *CommBuffer,
  IN  OUT UINTN                     *CommBufferSize
  )
/*++

Routine Description:
  SMI handler to enable ACPI mode

  Dispatched on reads from APM port with value 0xA0

  Disables the SW SMI Timer.
  ACPI events are disabled and ACPI event status is cleared.
  SCI mode is then enabled.

   Disable SW SMI Timer

   Clear all ACPI event status and disable all ACPI events
   Disable PM sources except power button
   Clear status bits

   Disable GPE0 sources
   Clear status bits

   Disable GPE1 sources
   Clear status bits

   Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)

   Enable SCI

Arguments:
  DispatchHandle  - EFI Handle
  DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT

Returns:
  Nothing

--*/
{
  EFI_STATUS  Status;
  UINT32      SmiEn;
  UINT16      Pm1Cnt;
  UINT8       Data8;

  Status  = GetAllQncPmBase (gSmst);
  ASSERT_EFI_ERROR (Status);

  SmiEn = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE);

  //
  // Disable SW SMI Timer
  //
  SmiEn &= ~(B_QNC_GPE0BLK_SMIE_SWT);
  IoWrite32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE, SmiEn);

  //
  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
  //
  Data8 = RTC_ADDRESS_REGISTER_D;
  IoWrite8 (R_IOPORT_CMOS_STANDARD_INDEX, Data8);
  Data8 = 0x0;
  IoWrite8 (R_IOPORT_CMOS_STANDARD_DATA, Data8);

  //
  // Enable SCI
  //
  Pm1Cnt = IoRead16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C);
  Pm1Cnt |= B_QNC_PM1BLK_PM1C_SCIEN;
  IoWrite16 (mAcpiSmm.QncPmBase + R_QNC_PM1BLK_PM1C, Pm1Cnt);

  //
  // Do platform specific stuff for ACPI enable SMI
  //


  return EFI_SUCCESS;
}
Пример #27
0
EFI_STATUS
RtcPowerFailureHandler (
  IN CONST EFI_PEI_SERVICES       **PeiServices
  )
{

  UINT16          DataUint16;
  UINT8           DataUint8;
  BOOLEAN         RtcUipIsAlwaysSet;
  DataUint16        = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
  RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
  if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {
    //
    // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
    //
    // Step 1.
    // BIOS clears this bit by writing a '0' to it.
    //
    if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
      //
      // Set to invalid date in order to reset the time to
      // BIOS build time later in the boot (SBRUN.c file).
      //
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);

      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
      IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
      IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
    }

    //
    // Step 2.
    // Set RTC Register 0Ah[6:4] to '110' or '111'.
    //
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
    IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));

    //
    // Step 3.
    // Set RTC Register 0Bh[7].
    //
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);

    //
    // Step 4.
    // Set RTC Register 0Ah[6:4] to '010'.
    //
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
    IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));

    //
    // Step 5.
    // Clear RTC Register 0Bh[7].
    //
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
    DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);
    IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
    IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
  }

  return EFI_SUCCESS;
}
Пример #28
0
/**
  This is the entrypoint of PEIM

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS if it completed successfully.
**/
EFI_STATUS
EFIAPI
CbPeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS Status;
  UINT64 LowMemorySize, HighMemorySize;
  UINT64 PeiMemSize = SIZE_64MB;   // 64 MB
  EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
  UINT32               RegEax;
  UINT8                PhysicalAddressBits;
  VOID*                pCbHeader;
  VOID*                pAcpiTable;
  UINT32               AcpiTableSize;
  VOID*                pSmbiosTable;
  UINT32               SmbiosTableSize;
  SYSTEM_TABLE_INFO*   pSystemTableInfo;
  FRAME_BUFFER_INFO    FbInfo;
  FRAME_BUFFER_INFO*   pFbInfo;
  ACPI_BOARD_INFO*     pAcpiBoardInfo;
  UINTN                PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;

  LowMemorySize = 0;
  HighMemorySize = 0;

  Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);
  if (EFI_ERROR(Status))
    return Status;

  DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%lx.\n", LowMemorySize));
  DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%lx.\n", HighMemorySize));

  ASSERT (LowMemorySize > 0);

  BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0),
    (UINT64)(0xA0000)
    );


  BuildResourceDescriptorHob (
    EFI_RESOURCE_MEMORY_RESERVED,
    (
    EFI_RESOURCE_ATTRIBUTE_PRESENT |
    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    EFI_RESOURCE_ATTRIBUTE_TESTED |
    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0xA0000),
    (UINT64)(0x60000)
    );

   BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
       EFI_RESOURCE_ATTRIBUTE_PRESENT |
       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
       EFI_RESOURCE_ATTRIBUTE_TESTED |
       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000),
    (UINT64) (LowMemorySize - 0x100000)
    );

  if (HighMemorySize > 0) {
    BuildResourceDescriptorHob (
    EFI_RESOURCE_SYSTEM_MEMORY,
    (
       EFI_RESOURCE_ATTRIBUTE_PRESENT |
       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    ),
    (EFI_PHYSICAL_ADDRESS)(0x100000000ULL),
    HighMemorySize
    );
  }

  //
  // Should be 64k aligned
  //
  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));

  DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
  DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));

  Status = PeiServicesInstallPeiMemory (
         PeiMemBase,
         PeiMemSize
         );
  ASSERT_EFI_ERROR (Status);

  //
  // Set cache on the physical memory
  //
  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);

  //
  // Create Memory Type Information HOB
  //
  BuildGuidDataHob (
    &gEfiMemoryTypeInformationGuid,
    mDefaultMemoryTypeInformation,
    sizeof(mDefaultMemoryTypeInformation)
    );

  //
  // Create Fv hob
  //
  CbPeiReportRemainedFvs ();

  BuildMemoryAllocationHob (
    PcdGet32 (PcdPayloadFdMemBase),
    PcdGet32 (PcdPayloadFdMemSize),
    EfiBootServicesData
    );

  //
  // Build CPU memory space and IO space hob
  //
  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
  if (RegEax >= 0x80000008) {
    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
    PhysicalAddressBits = (UINT8) RegEax;
  } else {
    PhysicalAddressBits  = 36;
  }
  //
  // Create a CPU hand-off information
  //
  BuildCpuHob (PhysicalAddressBits, 16);

  //
  // Report Local APIC range
  //
  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);

  //
  // Boot mode
  //
  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesInstallPpi (mPpiBootMode);
  ASSERT_EFI_ERROR (Status);

   //
  // Set pcd to save the upper coreboot header in case the dxecore will
  // erase 0~4k memory
  //
  pCbHeader = NULL;
  if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
    && ((UINTN)pCbHeader > BASE_4KB)) {
    DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
    PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
  }

  //
  // Create guid hob for system tables like acpi table and smbios table
  //
  pAcpiTable = NULL;
  AcpiTableSize = 0;
  pSmbiosTable = NULL;
  SmbiosTableSize = 0;
  Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
  if (EFI_ERROR (Status)) {
    // ACPI table is oblidgible
    DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
    ASSERT (FALSE);
  }
  CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);

  pSystemTableInfo = NULL;
  pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
  ASSERT (pSystemTableInfo != NULL);
  pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
  pSystemTableInfo->AcpiTableSize = AcpiTableSize;
  pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
  pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
  DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
  DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
  DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));

  //
  // Create guid hob for acpi board information
  //
  Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue);
  ASSERT_EFI_ERROR (Status);
  pAcpiBoardInfo = NULL;
  pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
  ASSERT (pAcpiBoardInfo != NULL);
  pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
  pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
  pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
  pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
  DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));

  //
  // Create guid hob for frame buffer information
  //
  ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
  Status = CbParseFbInfo (&FbInfo);
  if (!EFI_ERROR (Status)) {
    pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
    ASSERT (pSystemTableInfo != NULL);
    CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
    DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
  }

  //
  // Mask off all legacy 8259 interrupt sources
  //
  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE,  0xFF);

  return EFI_SUCCESS;
}
Пример #29
0
/**

  This function is IO instruction handler for SMM.

  @param Index CPU index

**/
VOID
SmmIoHandler (
  IN UINT32 Index
  )
{
  VM_EXIT_QUALIFICATION   Qualification;
  UINT16                  Port;
  UINTN                   *DataPtr;
  UINTN                   LinearAddr;
  X86_REGISTER            *Reg;
  STM_RSC_IO_DESC         *IoDesc;
  STM_RSC_PCI_CFG_DESC    *PciCfgDesc;
  UINT32                  PciAddress;
  STM_RSC_IO_DESC         LocalIoDesc;
  STM_RSC_PCI_CFG_DESC    *LocalPciCfgDescPtr;
  UINT8                   LocalPciCfgDescBuf[STM_LOG_ENTRY_SIZE];

  Reg = &mGuestContextCommonSmm.GuestContextPerCpu[Index].Register;

  Qualification.UintN = VmReadN (VMCS_N_RO_EXIT_QUALIFICATION_INDEX);

  if (Qualification.IoInstruction.Operand != 0) {
    Port = (UINT16)Qualification.IoInstruction.PortNum;
  } else {
    Port = (UINT16)Reg->Rdx;
  }
  DataPtr = (UINTN *)&Reg->Rax;

  //
  // We need handle case that CF9 is protected, but CF8, CFC need to be pass-through.
  // But DWORD CF8 programming will be caught here.
  // So add check here. CF8 will be bypassed, because it does not in CF9 scope.
  //
  IoDesc = GetStmResourceIo (mHostContextCommon.MleProtectedResource.Base, Port);
  if (IoDesc != NULL) {
    DEBUG ((EFI_D_ERROR, "IO violation!\n"));
    AddEventLogForResource (EvtHandledProtectionException, (STM_RSC *)IoDesc);
    SmmExceptionHandler (Index);
    CpuDeadLoop ();
  }

  IoDesc = GetStmResourceIo ((STM_RSC *)(UINTN)mGuestContextCommonSmm.BiosHwResourceRequirementsPtr, Port);
  if (IoDesc == NULL) {
    ZeroMem (&LocalIoDesc, sizeof(LocalIoDesc));
    LocalIoDesc.Hdr.RscType = IO_RANGE;
    LocalIoDesc.Hdr.Length = sizeof(LocalIoDesc);
    LocalIoDesc.Base = Port;
    LocalIoDesc.Length = (UINT16)(Qualification.IoInstruction.Size + 1);
    AddEventLogForResource (EvtBiosAccessToUnclaimedResource, (STM_RSC *)&LocalIoDesc);
  }

  //
  // Check PCI - 0xCF8, 0xCFC~0xCFF access
  //
  if (Port == 0xCF8) {
    // Access PciAddress

    //
    // We need make sure PciAddress access and PciData access is atomic.
    //
    AcquireSpinLock (&mHostContextCommon.PciLock);
  }
  if ((Port >= 0xCFC) && (Port <= 0xCFF)) {
    // Access PciData

    //
    // AcquireLock to prevent 0xCF8 access
    //
    AcquireSpinLock (&mHostContextCommon.PciLock);
    PciAddress = IoRead32 (0xCF8);
    PciCfgDesc = GetStmResourcePci (
                   mHostContextCommon.MleProtectedResource.Base,
                   BUS_FROM_CF8_ADDRESS(PciAddress),
                   DEVICE_FROM_CF8_ADDRESS(PciAddress),
                   FUNCTION_FROM_CF8_ADDRESS(PciAddress),
                   REGISTER_FROM_CF8_ADDRESS(PciAddress) + (Port & 0x3),
                   (Qualification.IoInstruction.Direction != 0) ? STM_RSC_PCI_CFG_R : STM_RSC_PCI_CFG_W
                   );
    if (PciCfgDesc != NULL) {
      DEBUG ((EFI_D_ERROR, "IO (PCI) violation!\n"));
      AddEventLogForResource (EvtHandledProtectionException, (STM_RSC *)PciCfgDesc);
      ReleaseSpinLock (&mHostContextCommon.PciLock);
      SmmExceptionHandler (Index);
      CpuDeadLoop ();
    }

    PciCfgDesc = GetStmResourcePci (
                   (STM_RSC *)(UINTN)mGuestContextCommonSmm.BiosHwResourceRequirementsPtr,
                   BUS_FROM_CF8_ADDRESS(PciAddress),
                   DEVICE_FROM_CF8_ADDRESS(PciAddress),
                   FUNCTION_FROM_CF8_ADDRESS(PciAddress),
                   REGISTER_FROM_CF8_ADDRESS(PciAddress) + (Port & 0x3),
                   (Qualification.IoInstruction.Direction != 0) ? STM_RSC_PCI_CFG_R : STM_RSC_PCI_CFG_W
                   );
    if (PciCfgDesc == NULL) {
      DEBUG((EFI_D_ERROR, "Add unclaimed PCI_RSC!\n"));
      LocalPciCfgDescPtr = (STM_RSC_PCI_CFG_DESC *)LocalPciCfgDescBuf;
      ZeroMem (LocalPciCfgDescBuf, sizeof(LocalPciCfgDescBuf));
      LocalPciCfgDescPtr->Hdr.RscType = PCI_CFG_RANGE;
      LocalPciCfgDescPtr->Hdr.Length = sizeof(STM_RSC_PCI_CFG_DESC); // BUGBUG: Just report this PCI device, it is hard to create PCI hierachy here.
      LocalPciCfgDescPtr->RWAttributes = (Qualification.IoInstruction.Direction != 0) ? STM_RSC_PCI_CFG_R : STM_RSC_PCI_CFG_W;
      LocalPciCfgDescPtr->Base = REGISTER_FROM_CF8_ADDRESS(PciAddress) + (Port & 0x3);
      LocalPciCfgDescPtr->Length = (UINT16)(Qualification.IoInstruction.Size + 1);
      LocalPciCfgDescPtr->OriginatingBusNumber = BUS_FROM_CF8_ADDRESS(PciAddress);
      LocalPciCfgDescPtr->LastNodeIndex = 0;
      LocalPciCfgDescPtr->PciDevicePath[0].Type = 1;
      LocalPciCfgDescPtr->PciDevicePath[0].Subtype = 1;
      LocalPciCfgDescPtr->PciDevicePath[0].Length = sizeof(STM_PCI_DEVICE_PATH_NODE);
      LocalPciCfgDescPtr->PciDevicePath[0].PciFunction = FUNCTION_FROM_CF8_ADDRESS(PciAddress);
      LocalPciCfgDescPtr->PciDevicePath[0].PciDevice = DEVICE_FROM_CF8_ADDRESS(PciAddress);
      AddEventLogForResource (EvtBiosAccessToUnclaimedResource, (STM_RSC *)LocalPciCfgDescPtr);
    }
  }

  if (Qualification.IoInstruction.Rep != 0) {
    UINT64 RcxMask;

    RcxMask = 0xFFFFFFFFFFFFFFFFull;
    if ((mGuestContextCommonSmm.GuestContextPerCpu[Index].Efer & IA32_EFER_MSR_MLA) == 0) {
      RcxMask = 0xFFFFFFFFull;
    }
    if ((Reg->Rcx & RcxMask) == 0) {
      // Skip
      if ((Port == 0xCF8) || ((Port >= 0xCFC) && (Port <= 0xCFF))) {
        ReleaseSpinLock (&mHostContextCommon.PciLock);
      }
      VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN(VMCS_N_GUEST_RIP_INDEX) + VmRead32(VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
      return ;
    }
  }

  if (Qualification.IoInstruction.String != 0) {
    LinearAddr = VmReadN (VMCS_N_RO_GUEST_LINEAR_ADDR_INDEX);
    if (VmReadN (VMCS_N_GUEST_CR0_INDEX) & CR0_PG) {
      DataPtr = (UINTN *)(UINTN)GuestLinearToHostPhysical (Index, LinearAddr);
    } else {
      DataPtr = (UINTN *)LinearAddr;
    }

    if ((VmReadN (VMCS_N_GUEST_RFLAGS_INDEX) & RFLAGS_DF) != 0) {
      if (Qualification.IoInstruction.Direction != 0) {
        Reg->Rdi -= Qualification.IoInstruction.Size + 1;
      } else {
        Reg->Rsi -= Qualification.IoInstruction.Size + 1;
      }
    } else {
      if (Qualification.IoInstruction.Direction != 0) {
        Reg->Rdi += Qualification.IoInstruction.Size + 1;
      } else {
        Reg->Rsi += Qualification.IoInstruction.Size + 1;
      }
    }
  }

  if (Qualification.IoInstruction.Direction != 0) { // IN
    switch (Qualification.IoInstruction.Size) {
    case 0:
      *(UINT8 *)DataPtr = IoRead8 (Port);
      goto Ret;
      break;
    case 1:
      *(UINT16 *)DataPtr = IoRead16 (Port);
      goto Ret;
      break;
    case 3:
      *(UINT32 *)DataPtr = IoRead32 (Port);
      goto Ret;
      break;
    default:
      break;
    }
  } else { // OUT
    switch (Qualification.IoInstruction.Size) {
    case 0:
      IoWrite8 (Port, (UINT8)*DataPtr);
      goto Ret;
      break;
    case 1:
      IoWrite16 (Port, (UINT16)*DataPtr);
      goto Ret;
      break;
    case 3:
      IoWrite32 (Port, (UINT32)*DataPtr);
      goto Ret;
      break;
    default:
      break;
    }
  }

  if ((Port == 0xCF8) || ((Port >= 0xCFC) && (Port <= 0xCFF))) {
    ReleaseSpinLock (&mHostContextCommon.PciLock);
  }
  DEBUG ((EFI_D_INFO, "!!!IoHandler!!!\n"));
  DumpVmcsAllField ();

  CpuDeadLoop ();

Ret:
  if ((Port == 0xCF8) || ((Port >= 0xCFC) && (Port <= 0xCFF))) {
    ReleaseSpinLock (&mHostContextCommon.PciLock);
  }
  if (Qualification.IoInstruction.Rep != 0) {
    // replay
    Reg->Rcx --;
    return ;
  }

  VmWriteN (VMCS_N_GUEST_RIP_INDEX, VmReadN(VMCS_N_GUEST_RIP_INDEX) + VmRead32(VMCS_32_RO_VMEXIT_INSTRUCTION_LENGTH_INDEX));
  return ;
}
Пример #30
0
VOID
EFIAPI
EnableAcpiCallback (
  IN  EFI_HANDLE                    DispatchHandle,
  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
  )
{
  UINT32 SmiEn;
  UINT16 Pm1Cnt;
  UINT16 wordValue;
  UINT32 RegData32;

  //
  // Disable SW SMI Timer
  //
  SmiEn = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
  SmiEn &= ~B_PCH_SMI_STS_SWSMI_TMR;
  IoWrite32(mAcpiBaseAddr + R_PCH_SMI_EN, SmiEn);

  wordValue = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS);
  if(wordValue & B_PCH_ACPI_PM1_STS_WAK) {
	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN), 0x0000);
	  IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS), 0xffffffff);
  }
  else {
		mPM1_SaveState16 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN);

		//
		// Disable PM sources except power button
		//
    // power button is enabled only for PCAT. Disabled it on Tablet platform
    //
    IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
		IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);

		mGPE_SaveState32 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN);
		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, 0x0000);
		IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);

  }

  //
  // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
  // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS RAM is no longer Valid
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);


	RegData32 = IoRead32(ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN);
	RegData32 &= ~(BIT7);
    IoWrite32((ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN), RegData32);


  //
  // Enable SCI
  //
  Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
  Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
  IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);


}