UartInit.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /** @file
  2. This PEIM will parse the hoblist from fsp and report them into pei core.
  3. This file contains the main entrypoint of the PEIM.
  4. Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiPei.h>
  8. #include <Library/IoLib.h>
  9. #include <Library/SerialPortLib.h>
  10. #define PCI_IDX 0xCF8
  11. #define PCI_DAT 0xCFC
  12. #define PCI_LPC_BASE (0x8000F800)
  13. #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))
  14. #define PMC_BASE_ADDRESS 0xFED03000 // PMC Memory Base Address
  15. #define R_PCH_LPC_PMC_BASE 0x44 // PBASE, 32bit, 512 Bytes
  16. #define B_PCH_LPC_PMC_BASE_EN BIT1 // Enable Bit
  17. #define R_PCH_PMC_GEN_PMCON_1 0x20 // General PM Configuration 1
  18. #define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR BIT14 // SUS Well Power Failure
  19. #define B_PCH_PMC_GEN_PMCON_PWROK_FLR BIT16 // PWROK Failure
  20. #define R_PCH_LPC_UART_CTRL 0x80 // UART Control
  21. #define B_PCH_LPC_UART_CTRL_COM1_EN BIT0 // COM1 Enable
  22. #define ILB_BASE_ADDRESS 0xFED08000 // ILB Memory Base Address
  23. #define R_PCH_ILB_IRQE 0x88 // IRQ Enable Control
  24. #define IO_BASE_ADDRESS 0xFED0C000 // IO Memory Base Address
  25. #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable
  26. #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ4 BIT4 // UART IRQ4 Enable
  27. #define PCIEX_BASE_ADDRESS 0xE0000000
  28. #define PCI_EXPRESS_BASE_ADDRESS PCIEX_BASE_ADDRESS
  29. #define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
  30. #define SB_RCBA 0xfed1c000
  31. typedef enum {
  32. PchA0 = 0,
  33. PchA1 = 1,
  34. PchB0 = 2,
  35. PchB1 = 3,
  36. PchB2 = 4,
  37. PchB3 = 5,
  38. PchC0 = 6,
  39. PchSteppingMax
  40. } PCH_STEPPING;
  41. #define MmPciAddress( Segment, Bus, Device, Function, Register ) \
  42. ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
  43. (UINTN)(Bus << 20) + \
  44. (UINTN)(Device << 15) + \
  45. (UINTN)(Function << 12) + \
  46. (UINTN)(Register) \
  47. )
  48. #define DEFAULT_PCI_BUS_NUMBER_PCH 0
  49. #define PCI_DEVICE_NUMBER_PCH_LPC 31
  50. #define PCI_FUNCTION_NUMBER_PCH_LPC 0
  51. #define R_PCH_LPC_RID_CC 0x08 // Revision ID & Class Code
  52. #define V_PCH_LPC_RID_0 0x01 // A0 Stepping (17 x 17)
  53. #define V_PCH_LPC_RID_1 0x02 // A0 Stepping (25 x 27)
  54. #define V_PCH_LPC_RID_2 0x03 // A1 Stepping (17 x 17)
  55. #define V_PCH_LPC_RID_3 0x04 // A1 Stepping (25 x 27)
  56. #define V_PCH_LPC_RID_4 0x05 // B0 Stepping (17 x 17)
  57. #define V_PCH_LPC_RID_5 0x06 // B0 Stepping (25 x 27)
  58. #define V_PCH_LPC_RID_6 0x07 // B1 Stepping (17 x 17)
  59. #define V_PCH_LPC_RID_7 0x08 // B1 Stepping (25 x 27)
  60. #define V_PCH_LPC_RID_8 0x09 // B2 Stepping (17 x 17)
  61. #define V_PCH_LPC_RID_9 0x0A // B2 Stepping (25 x 27)
  62. #define V_PCH_LPC_RID_A 0x0B // B3 Stepping (17 x 17)
  63. #define V_PCH_LPC_RID_B 0x0C // B3 Stepping (25 x 27)
  64. #define V_PCH_LPC_RID_C 0x0D // C0 Stepping (17 x 17)
  65. #define V_PCH_LPC_RID_D 0x0E // C0 Stepping (25 x 27)
  66. /**
  67. Return Pch stepping type
  68. @param[in] None
  69. @retval PCH_STEPPING Pch stepping type
  70. **/
  71. PCH_STEPPING
  72. EFIAPI
  73. PchStepping (
  74. VOID
  75. )
  76. {
  77. UINT8 RevId;
  78. RevId = MmioRead8 (
  79. MmPciAddress (0,
  80. DEFAULT_PCI_BUS_NUMBER_PCH,
  81. PCI_DEVICE_NUMBER_PCH_LPC,
  82. PCI_FUNCTION_NUMBER_PCH_LPC,
  83. R_PCH_LPC_RID_CC)
  84. );
  85. switch (RevId) {
  86. case V_PCH_LPC_RID_0:
  87. case V_PCH_LPC_RID_1:
  88. return PchA0;
  89. break;
  90. case V_PCH_LPC_RID_2:
  91. case V_PCH_LPC_RID_3:
  92. return PchA1;
  93. break;
  94. case V_PCH_LPC_RID_4:
  95. case V_PCH_LPC_RID_5:
  96. return PchB0;
  97. break;
  98. case V_PCH_LPC_RID_6:
  99. case V_PCH_LPC_RID_7:
  100. return PchB1;
  101. break;
  102. case V_PCH_LPC_RID_8:
  103. case V_PCH_LPC_RID_9:
  104. return PchB2;
  105. break;
  106. case V_PCH_LPC_RID_A:
  107. case V_PCH_LPC_RID_B:
  108. return PchB3;
  109. break;
  110. case V_PCH_LPC_RID_C:
  111. case V_PCH_LPC_RID_D:
  112. return PchC0;
  113. break;
  114. default:
  115. return PchSteppingMax;
  116. break;
  117. }
  118. }
  119. /**
  120. Enable legacy decoding on ICH6
  121. @param[in] none
  122. @retval EFI_SUCCESS Always returns success.
  123. **/
  124. VOID
  125. EnableInternalUart(
  126. VOID
  127. )
  128. {
  129. //
  130. // Program and enable PMC Base.
  131. //
  132. IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
  133. IoWrite32 (PCI_DAT, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
  134. //
  135. // Enable COM1 for debug message output.
  136. //
  137. MmioAndThenOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, (UINT32) (~(B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR + B_PCH_PMC_GEN_PMCON_PWROK_FLR)), BIT24);
  138. //
  139. // Silicon Steppings
  140. //
  141. if (PchStepping()>= PchB0)
  142. MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4);
  143. else
  144. MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
  145. MmioAnd32(IO_BASE_ADDRESS + 0x0520, (UINT32)~(0x00000187));
  146. MmioOr32 (IO_BASE_ADDRESS + 0x0520, (UINT32)0x81); // UART3_RXD-L
  147. MmioAnd32(IO_BASE_ADDRESS + 0x0530, (UINT32)~(0x00000007));
  148. MmioOr32 (IO_BASE_ADDRESS + 0x0530, (UINT32)0x1); // UART3_RXD-L
  149. MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);
  150. SerialPortInitialize ();
  151. SerialPortWrite ((UINT8 *)"EnableInternalUart!\r\n", sizeof("EnableInternalUart!\r\n") - 1);
  152. return ;
  153. }