From 24ca2f3507056e6a86cb0c0f088bba96cd117d71 Mon Sep 17 00:00:00 2001 From: "Leahy, Leroy P" Date: Mon, 9 May 2016 10:57:55 -0700 Subject: [PATCH] CorebootPayloadPkg/PlatformBdsLib: Pass more serial parameters Pass the serial port baudrate, register stride, input clock rate and ID from coreboot to CorebootPayloadPkg. Change-Id: I37111d23216e4effa2909337af7e8a6de36b61f7 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Lee Leahy Reviewed-by: Prince Agyeman --- CorebootModulePkg/Include/Coreboot.h | 17 +++++- .../Include/Library/CbParseLib.h | 26 +++++---- .../Library/CbParseLib/CbParseLib.c | 32 ++++++++--- .../Library/PlatformBdsLib/BdsPlatform.c | 5 ++ .../Library/PlatformBdsLib/PlatformBdsLib.inf | 6 +++ .../Library/PlatformHookLib/PlatformHookLib.c | 53 ++++++++++++++++++- .../PlatformHookLib/PlatformHookLib.inf | 12 +++-- 7 files changed, 128 insertions(+), 23 deletions(-) diff --git a/CorebootModulePkg/Include/Coreboot.h b/CorebootModulePkg/Include/Coreboot.h index f2f18be2cc..784e0b128a 100644 --- a/CorebootModulePkg/Include/Coreboot.h +++ b/CorebootModulePkg/Include/Coreboot.h @@ -80,7 +80,7 @@ struct imd_root { UINT32 max_entries; UINT32 num_entries; UINT32 flags; - UINT32 entry_align; + UINT32 entry_align; UINT32 max_offset; struct imd_entry entries[0]; }; @@ -165,6 +165,21 @@ struct cb_serial { UINT32 type; UINT32 baseaddr; UINT32 baud; + UINT32 regwidth; + + // Crystal or input frequency to the chip containing the UART. + // Provide the board specific details to allow the payload to + // initialize the chip containing the UART and make independent + // decisions as to which dividers to select and their values + // to eventually arrive at the desired console baud-rate. + UINT32 input_hertz; + + // UART PCI address: bus, device, function + // 1 << 31 - Valid bit, PCI UART in use + // Bus << 20 + // Device << 15 + // Function << 12 + UINT32 uart_pci_addr; }; #define CB_TAG_CONSOLE 0x00010 diff --git a/CorebootModulePkg/Include/Library/CbParseLib.h b/CorebootModulePkg/Include/Library/CbParseLib.h index 170375b365..a023246d71 100644 --- a/CorebootModulePkg/Include/Library/CbParseLib.h +++ b/CorebootModulePkg/Include/Library/CbParseLib.h @@ -30,7 +30,7 @@ CbParseMemoryInfo ( IN UINT64* pLowMemorySize, IN UINT64* pHighMemorySize ); - + /** Acquire the coreboot memory table with the given table id @@ -45,11 +45,11 @@ CbParseMemoryInfo ( **/ RETURN_STATUS CbParseCbMemTable ( - IN UINT32 TableId, + IN UINT32 TableId, IN VOID** pMemTable, IN UINT32* pMemTableSize ); - + /** Acquire the acpi table from coreboot @@ -66,7 +66,7 @@ CbParseAcpiTable ( IN VOID** pMemTable, IN UINT32* pMemTableSize ); - + /** Acquire the smbios table from coreboot @@ -83,7 +83,7 @@ CbParseSmbiosTable ( IN VOID** pMemTable, IN UINT32* pMemTableSize ); - + /** Find the required fadt information @@ -107,13 +107,16 @@ CbParseFadtInfo ( IN UINTN* pPmEvtReg, IN UINTN* pPmGpeEnReg ); - + /** Find the serial port information @param pRegBase Pointer to the base address of serial port registers @param pRegAccessType Pointer to the access type of serial port registers + @param pRegWidth Pointer to the register width in bytes @param pBaudrate Pointer to the serial port baudrate + @param pInputHertz Pointer to the input clock frequency + @param pUartPciAddr Pointer to the UART PCI bus, dev and func address @retval RETURN_SUCCESS Successfully find the serial port information. @retval RETURN_NOT_FOUND Failed to find the serial port information . @@ -121,9 +124,12 @@ CbParseFadtInfo ( **/ RETURN_STATUS CbParseSerialInfo ( - IN UINT32* pRegBase, - IN UINT32* pRegAccessType, - IN UINT32* pBaudrate + OUT UINT32 *pRegBase, + OUT UINT32 *pRegAccessType, + OUT UINT32 *pRegWidth, + OUT UINT32 *pBaudrate, + OUT UINT32 *pInputHertz, + OUT UINT32 *pUartPciAddr ); /** @@ -141,7 +147,7 @@ CbParseGetCbHeader ( IN UINTN Level, IN VOID** HeaderPtr ); - + /** Find the video frame buffer information diff --git a/CorebootModulePkg/Library/CbParseLib/CbParseLib.c b/CorebootModulePkg/Library/CbParseLib/CbParseLib.c index 377abf3c67..7c81a51054 100644 --- a/CorebootModulePkg/Library/CbParseLib/CbParseLib.c +++ b/CorebootModulePkg/Library/CbParseLib/CbParseLib.c @@ -33,7 +33,7 @@ @return the UNIT64 value after convertion. **/ -UINT64 +UINT64 cb_unpack64 ( IN struct cbuint64 val ) @@ -469,12 +469,12 @@ CbParseFadtInfo ( } DEBUG ((EFI_D_INFO, "Reset Value 0x%x\n", Fadt->ResetValue)); - if (pPmEvtReg != NULL) { + if (pPmEvtReg != NULL) { *pPmEvtReg = Fadt->Pm1aEvtBlk; DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk)); } - if (pPmGpeEnReg != NULL) { + if (pPmGpeEnReg != NULL) { *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2; DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg)); } @@ -519,15 +519,15 @@ CbParseFadtInfo ( *pResetValue = Fadt->ResetValue; DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue)); - if (pPmEvtReg != NULL) { + if (pPmEvtReg != NULL) { *pPmEvtReg = Fadt->Pm1aEvtBlk; DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk)); } - if (pPmGpeEnReg != NULL) { + if (pPmGpeEnReg != NULL) { *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2; DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg)); - } + } return RETURN_SUCCESS; } } @@ -541,7 +541,10 @@ CbParseFadtInfo ( @param pRegBase Pointer to the base address of serial port registers @param pRegAccessType Pointer to the access type of serial port registers + @param pRegWidth Pointer to the register width in bytes @param pBaudrate Pointer to the serial port baudrate + @param pInputHertz Pointer to the input clock frequency + @param pUartPciAddr Pointer to the UART PCI bus, dev and func address @retval RETURN_SUCCESS Successfully find the serial port information. @retval RETURN_NOT_FOUND Failed to find the serial port information . @@ -551,7 +554,10 @@ RETURN_STATUS CbParseSerialInfo ( OUT UINT32 *pRegBase, OUT UINT32 *pRegAccessType, - OUT UINT32 *pBaudrate + OUT UINT32 *pRegWidth, + OUT UINT32 *pBaudrate, + OUT UINT32 *pInputHertz, + OUT UINT32 *pUartPciAddr ) { struct cb_serial *CbSerial; @@ -569,6 +575,10 @@ CbParseSerialInfo ( *pRegBase = CbSerial->baseaddr; } + if (pRegWidth != NULL) { + *pRegWidth = CbSerial->regwidth; + } + if (pRegAccessType != NULL) { *pRegAccessType = CbSerial->type; } @@ -577,6 +587,14 @@ CbParseSerialInfo ( *pBaudrate = CbSerial->baud; } + if (pInputHertz != NULL) { + *pInputHertz = CbSerial->input_hertz; + } + + if (pUartPciAddr != NULL) { + *pUartPciAddr = CbSerial->uart_pci_addr; + } + return RETURN_SUCCESS; } diff --git a/CorebootPayloadPkg/Library/PlatformBdsLib/BdsPlatform.c b/CorebootPayloadPkg/Library/PlatformBdsLib/BdsPlatform.c index ef6a1b26ca..c0a2b19645 100644 --- a/CorebootPayloadPkg/Library/PlatformBdsLib/BdsPlatform.c +++ b/CorebootPayloadPkg/Library/PlatformBdsLib/BdsPlatform.c @@ -78,6 +78,10 @@ PlatformBdsInit ( VOID ) { + gUartDeviceNode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); + gUartDeviceNode.DataBits = PcdGet8 (PcdUartDefaultDataBits); + gUartDeviceNode.Parity = PcdGet8 (PcdUartDefaultParity); + gUartDeviceNode.StopBits = PcdGet8 (PcdUartDefaultStopBits); } @@ -786,6 +790,7 @@ PlatformBdsPolicyBehavior ( DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n")); + PlatformBdsInit(); ConnectRootBridge (); // diff --git a/CorebootPayloadPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/CorebootPayloadPkg/Library/PlatformBdsLib/PlatformBdsLib.inf index 9c102721d5..b1a79b866c 100644 --- a/CorebootPayloadPkg/Library/PlatformBdsLib/PlatformBdsLib.inf +++ b/CorebootPayloadPkg/Library/PlatformBdsLib/PlatformBdsLib.inf @@ -45,6 +45,12 @@ DebugLib PcdLib GenericBdsLib + PlatformHookLib + [Pcd] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits diff --git a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c index 8449997050..b1cfb8e2c0 100644 --- a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c +++ b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c @@ -14,10 +14,23 @@ #include #include +#include #include #include #include +typedef struct { + UINT16 VendorId; ///< Vendor ID to match the PCI device. The value 0xFFFF terminates the list of entries. + UINT16 DeviceId; ///< Device ID to match the PCI device + UINT32 ClockRate; ///< UART clock rate. Set to 0 for default clock rate of 1843200 Hz + UINT64 Offset; ///< The byte offset into to the BAR + UINT8 BarIndex; ///< Which BAR to get the UART base address + UINT8 RegisterStride; ///< UART register stride in bytes. Set to 0 for default register stride of 1 byte. + UINT16 ReceiveFifoDepth; ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes. + UINT16 TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes. + UINT8 Reserved[2]; +} PCI_SERIAL_PARAMETER; + /** Performs platform specific initialization required for the CPU to access the hardware associated with a SerialPortLib instance. This function does @@ -38,8 +51,16 @@ PlatformHookSerialPortInitialize ( RETURN_STATUS Status; UINT32 SerialRegBase; UINT32 SerialRegAccessType; + UINT32 BaudRate; + UINT32 RegWidth; + UINT32 InputHertz; + UINT32 PayloadParam; + UINT32 DeviceVendor; + PCI_SERIAL_PARAMETER *SerialParam; - Status = CbParseSerialInfo (&SerialRegBase, &SerialRegAccessType, NULL); + Status = CbParseSerialInfo (&SerialRegBase, &SerialRegAccessType, + &RegWidth, &BaudRate, &InputHertz, + &PayloadParam); if (RETURN_ERROR (Status)) { return Status; } @@ -57,6 +78,34 @@ PlatformHookSerialPortInitialize ( return Status; } + Status = PcdSet32S (PcdSerialRegisterStride, RegWidth); + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = PcdSet32S (PcdSerialBaudRate, BaudRate); + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = PcdSet64S (PcdUartDefaultBaudRate, BaudRate); + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = PcdSet32S (PcdSerialClockRate, InputHertz); + if (RETURN_ERROR (Status)) { + return Status; + } + + if (PayloadParam >= 0x80000000) { + DeviceVendor = PciRead32 (PayloadParam & 0x0ffff000); + SerialParam = PcdGetPtr(PcdPciSerialParameters); + SerialParam->VendorId = (UINT16)DeviceVendor; + SerialParam->DeviceId = DeviceVendor >> 16; + SerialParam->ClockRate = InputHertz; + SerialParam->RegisterStride = (UINT8)RegWidth; + } + return RETURN_SUCCESS; } - diff --git a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf index e5db75fa95..3230105901 100644 --- a/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf +++ b/CorebootPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf @@ -19,6 +19,7 @@ MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = PlatformHookLib + CONSTRUCTOR = PlatformHookSerialPortInitialize [Sources] PlatformHookLib.c @@ -26,6 +27,7 @@ [LibraryClasses] CbParseLib PcdLib + PciLib [Packages] MdePkg/MdePkg.dec @@ -33,6 +35,10 @@ CorebootModulePkg/CorebootModulePkg.dec [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## PRODUCES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## PRODUCES - + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## PRODUCES + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## PRODUCES + gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters ## PRODUCES