Implement SerialPortLib and PlatformHookLib with System76EcLib

This commit is contained in:
Jeremy Soller
2020-07-02 11:25:17 -06:00
committed by Jeremy Soller
parent c6f1c4e654
commit e30d17a0d2
10 changed files with 142 additions and 187 deletions

View File

@@ -6,98 +6,139 @@
**/
#include <Library/System76EcLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
#define SYSTEM76_EC_BASE 0xE00
#define CMD_PRINT 0x4
// From coreboot/src/drivers/system76_ec/system76_ec.c {
#define SYSTEM76_EC_BASE 0x0E00
/**
@param Offset The offset into the SFMI RAM window to read from.
@return The value read.
**/
STATIC
UINT8
System76EcReadByte (
UINT8 Offset
)
{
return IoRead8 (SYSTEM76_EC_BASE + Offset);
static inline UINT8 system76_ec_read(UINT8 addr) {
return IoRead8(SYSTEM76_EC_BASE + (UINT16)addr);
}
/**
@param Offset The offset into the SFMI RAM window to write to.
@param Value The value to write.
@return The value written back to the I/O port.
**/
STATIC
UINT8
System76EcWriteByte (
UINT8 Offset,
UINT8 Value
)
{
return IoWrite8 (SYSTEM76_EC_BASE + Offset, Value);
static inline void system76_ec_write(UINT8 addr, UINT8 data) {
IoWrite8(SYSTEM76_EC_BASE + (UINT16)addr, data);
}
/**
Write data to the embedded controller using SMFI command interface.
@param Buffer Pointer to the data buffer to be written.
@param NumberOfBytes Number of bytes to write.
@return -1 if the command failed, else the number of data bytes written.
**/
INTN
System76EcWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
UINTN Index;
UINTN Index2;
UINTN Timeout;
if (Buffer == NULL) {
return 0;
}
for (Index = 0; Index < NumberOfBytes;) {
if (System76EcReadByte (0) == 0) {
// Can write 256 bytes of data at a time
for (Index2 = 0; (Index2 < NumberOfBytes) && ((Index2 + 4) < 256); Index++, Index2++) {
System76EcWriteByte ((Index + 4), Buffer[Index]);
}
// Flags
System76EcWriteByte (2, 0);
// Length
System76EcWriteByte (3, Index2);
// Command
System76EcWriteByte (0, CMD_PRINT);
// Wait for command completion, for up to 1 second
for (Timeout = 1000000; Timeout > 0; Timeout--) {
if (System76EcReadByte (0) == 0)
break;
MicroSecondDelay (1);
}
if (Timeout == 0) {
// Error: Timeout occured
return -1;
}
if (System76EcReadByte (1) != 0) {
// Error: Command failed
return -1;
}
} else {
// Error: Command already running
return -1;
void system76_ec_init(void) {
// Clear entire command region
for (int i = 0; i < 256; i++) {
system76_ec_write((UINT8)i, 0);
}
}
return Index;
}
void system76_ec_flush(void) {
// Send command
system76_ec_write(0, 4);
// Wait for command completion
while (system76_ec_read(0) != 0) {}
// Clear length
system76_ec_write(3, 0);
}
void system76_ec_print(UINT8 byte) {
// Read length
UINT8 len = system76_ec_read(3);
// Write data at offset
system76_ec_write(len + 4, byte);
// Update length
system76_ec_write(3, len + 1);
// If we hit the end of the buffer, or were given a newline, flush
if (byte == '\n' || len >= 128) {
system76_ec_flush();
}
}
// } From coreboot/src/drivers/system76_ec/system76_ec.c
// Implement SerialPortLib {
#include <Library/SerialPortLib.h>
RETURN_STATUS
EFIAPI
SerialPortInitialize (
VOID
)
{
system76_ec_init();
return RETURN_SUCCESS;
}
UINTN
EFIAPI
SerialPortWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
if (Buffer == NULL) {
return 0;
}
if (NumberOfBytes == 0) {
system76_ec_flush();
return 0;
}
for(UINTN i = 0; i < NumberOfBytes; i++) {
system76_ec_print(Buffer[i]);
}
return NumberOfBytes;
}
BOOLEAN
EFIAPI
SerialPortPoll (
VOID
)
{
return FALSE;
}
RETURN_STATUS
EFIAPI
SerialPortGetControl (
OUT UINT32 *Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortSetControl (
IN UINT32 Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortSetAttributes (
IN OUT UINT64 *BaudRate,
IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *Timeout,
IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits,
IN OUT EFI_STOP_BITS_TYPE *StopBits
)
{
return RETURN_UNSUPPORTED;
}
// } Implement SerialPortLib
// Implement PlatformHookLib {
#include <Library/PlatformHookLib.h>
RETURN_STATUS
EFIAPI
PlatformHookSerialPortInitialize (
VOID
)
{
return RETURN_SUCCESS;
}
// } Implement PlatformHookLib

View File

@@ -21,7 +21,6 @@
[LibraryClasses]
IoLib
TimerLib
[Sources]
System76EcLib.c

View File

@@ -1,18 +0,0 @@
/** @file
System76 EC logging
Copyright (c) 2020 System76, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/System76EcLib.h>
INTN
System76EcWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}

View File

@@ -1,27 +0,0 @@
## @file
# System76 EC logging.
#
# Copyright (c) 2020, System76, Inc.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = System76EcLibNull
MODULE_UNI_FILE = System76EcLibNull.uni
FILE_GUID = 76ECF0DD-148B-4E48-8589-FC998823F8C2
MODULE_TYPE = BASE
VERSION_STRING = 0.1
LIBRARY_CLASS = System76EcLibNull
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
[Sources]
System76EcLibNull.c
[Pcd]

View File

@@ -1,13 +0,0 @@
// /** @file
// System76 EC logging.
//
// Copyright (c) 2020, System76, Inc.
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "System76 EC logging"
#string STR_MODULE_DESCRIPTION #language en-US "System76 EC logging."