mirror of https://review.coreboot.org/STM.git
Merge branch 'CB_console' into stmpe
This commit is contained in:
commit
1a05184b69
|
@ -55,4 +55,6 @@ add_subdirectory(StmPkg/EdkII/PcAtChipsetPkg/Library/SerialIoLib)
|
|||
add_subdirectory(StmPkg/EdkII/MdePkg/Library/BasePcdLibNull)
|
||||
add_subdirectory(StmPkg/Core)
|
||||
add_subdirectory(StmPkg/Library/StmPlatformLibNull)
|
||||
add_subdirectory(StmPkg/Library/coreboot)
|
||||
|
||||
|
||||
|
|
|
@ -94,9 +94,9 @@ void PeIoHandler( IN UINT32 CpuIndex)
|
|||
}
|
||||
|
||||
AcquireSpinLock (&mInternalDebugLock);
|
||||
SerialPortWrite ((UINT8 *)"(VM/PE) ", sizeof("(VM/PE) ") - 1);
|
||||
SerialPortWrite ((UINT8 *) PhysAddress, DataSize);
|
||||
SerialPortWrite ((UINT8 *)"\r", 1);
|
||||
DebugPortWrite ((UINT8 *)"(VM/PE) ", sizeof("(VM/PE) ") - 1);
|
||||
DebugPortWrite ((UINT8 *) PhysAddress, DataSize);
|
||||
DebugPortWrite ((UINT8 *) "\r", 1);
|
||||
ReleaseSpinLock (&mInternalDebugLock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -466,5 +466,32 @@ DebugClearMemoryEnabled (
|
|||
#define CR(Record, TYPE, Field, TestSignature) \
|
||||
BASE_CR (Record, TYPE, Field)
|
||||
#endif
|
||||
|
||||
/**
|
||||
Write data from buffer to device interface.
|
||||
|
||||
Writes NumberOfBytes data bytes from Buffer to the device interface.
|
||||
The number of bytes actually written to the serial device is returned.
|
||||
If the return value is less than NumberOfBytes, then the write operation failed.
|
||||
|
||||
If Buffer is NULL, then ASSERT().
|
||||
|
||||
If NumberOfBytes is zero, then return 0.
|
||||
|
||||
@param Buffer Pointer to the data buffer to be written.
|
||||
@param NumberOfBytes Number of bytes to written to the serial device.
|
||||
|
||||
@retval 0 NumberOfBytes is 0.
|
||||
@retval >0 The number of bytes written to the serial device.
|
||||
If this value is less than NumberOfBytes, then the read operation failed.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
DebugPortWrite (
|
||||
IN UINT8 *Buffer,
|
||||
IN UINTN NumberOfBytes
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -55,6 +55,12 @@ SerialPortWrite (
|
|||
IN UINT8 *Buffer,
|
||||
IN UINTN NumberOfBytes
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
SerialPortWriteSingle(
|
||||
IN UINT8 Buffer
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -73,6 +79,7 @@ SerialPortWrite (
|
|||
@retval >0 Actual number of bytes read from serial device.
|
||||
|
||||
**/
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
SerialPortRead (
|
||||
|
|
|
@ -142,17 +142,29 @@ SerialPortWrite (
|
|||
Result = NumberOfBytes;
|
||||
|
||||
while (NumberOfBytes--) {
|
||||
//
|
||||
// Wait for the serail port to be ready.
|
||||
//
|
||||
do {
|
||||
Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET);
|
||||
} while ((Data & LSR_TXRDY) == 0);
|
||||
IoWrite8 ((UINT16) gUartBase, *Buffer++);
|
||||
SerialPortWriteSingle(*Buffer++);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
SerialPortWriteSingle(
|
||||
IN UINT8 Buffer
|
||||
)
|
||||
{
|
||||
UINT8 Data;
|
||||
|
||||
//
|
||||
// Wait for the serail port to be ready.
|
||||
//
|
||||
do {
|
||||
Data = IoRead8 ((UINT16) gUartBase + LSR_OFFSET);
|
||||
} while ((Data & LSR_TXRDY) == 0);
|
||||
IoWrite8 ((UINT16) gUartBase, Buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,5 +9,6 @@ target_link_libraries(DebugLib PUBLIC
|
|||
PrintLib
|
||||
BaseLib
|
||||
SynchronizationLib
|
||||
corebootLib
|
||||
)
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/SerialPortLib.h>
|
||||
#include <Library/SynchronizationLib.h>
|
||||
|
||||
extern int init_cbcons(void);
|
||||
extern void coreboot_debug_putc(char c);
|
||||
|
||||
//
|
||||
// Define the maximum debug and assert message length that this library supports
|
||||
|
@ -37,6 +40,54 @@
|
|||
SPIN_LOCK mInternalDebugLock = SPIN_LOCK_RELEASED; // TBD: need call InitializeSpinLock
|
||||
|
||||
static int serial_initialized = 0;
|
||||
static int cbmem_initialized = 0;
|
||||
|
||||
/**
|
||||
Write data from buffer to device interface.
|
||||
|
||||
Writes NumberOfBytes data bytes from Buffer to the device interface.
|
||||
The number of bytes actually written to the serial device is returned.
|
||||
If the return value is less than NumberOfBytes, then the write operation failed.
|
||||
|
||||
If Buffer is NULL, then ASSERT().
|
||||
|
||||
If NumberOfBytes is zero, then return 0.
|
||||
|
||||
@param Buffer Pointer to the data buffer to be written.
|
||||
@param NumberOfBytes Number of bytes to written to the serial device.
|
||||
|
||||
@retval 0 NumberOfBytes is 0.
|
||||
@retval >0 The number of bytes written to the serial device.
|
||||
If this value is less than NumberOfBytes, then the read operation failed.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
DebugPortWrite (
|
||||
IN UINT8 *Buffer,
|
||||
IN UINTN NumberOfBytes
|
||||
)
|
||||
{
|
||||
UINTN Result;
|
||||
UINT8 Data;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result = NumberOfBytes;
|
||||
|
||||
while (NumberOfBytes--) {
|
||||
char c;
|
||||
SerialPortWriteSingle(*Buffer);
|
||||
c = (char) Buffer[0];
|
||||
coreboot_debug_putc(c);
|
||||
Buffer++;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prints a debug message to the debug output device if the specified error level is enabled.
|
||||
|
@ -73,7 +124,13 @@ DebugPrint (
|
|||
{
|
||||
serial_initialized = 1;
|
||||
SerialPortInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
if(cbmem_initialized == 0)
|
||||
{
|
||||
init_cbcons();
|
||||
cbmem_initialized = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Check driver debug mask value and global mask
|
||||
|
@ -93,8 +150,8 @@ DebugPrint (
|
|||
// Send the print string to a Serial Port
|
||||
//
|
||||
AcquireSpinLock (&mInternalDebugLock);
|
||||
SerialPortWrite ((UINT8 *)"(STM) ", sizeof("(STM) ") - 1);
|
||||
SerialPortWrite ((UINT8 *) Buffer, AsciiStrLen(Buffer));
|
||||
DebugPortWrite ((UINT8 *)"(STM) ", sizeof("(STM) ") - 1);
|
||||
DebugPortWrite ((UINT8 *) Buffer, AsciiStrLen(Buffer));
|
||||
ReleaseSpinLock (&mInternalDebugLock);
|
||||
}
|
||||
|
||||
|
@ -145,8 +202,8 @@ DebugAssert (
|
|||
// Send the print string to the Console Output device
|
||||
//
|
||||
AcquireSpinLock (&mInternalDebugLock);
|
||||
SerialPortWrite ((UINT8 *)"(STM) ", sizeof("(STM) ") - 1);
|
||||
SerialPortWrite ((UINT8 *) Buffer, AsciiStrLen(Buffer));
|
||||
DebugPortWrite ((UINT8 *)"(STM) ", sizeof("(STM) ") - 1);
|
||||
DebugPortWrite ((UINT8 *) Buffer, AsciiStrLen(Buffer));
|
||||
ReleaseSpinLock (&mInternalDebugLock);
|
||||
|
||||
//
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
add_library(corebootLib STATIC
|
||||
coreboot.c
|
||||
)
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
|
||||
#define CONFIG_DEBUG_COREBOOT 1
|
||||
|
||||
/****************************************************************
|
||||
* Memory map
|
||||
****************************************************************/
|
||||
|
||||
struct cb_header {
|
||||
UINT32 signature;
|
||||
UINT32 header_bytes;
|
||||
UINT32 header_checksum;
|
||||
UINT32 table_bytes;
|
||||
UINT32 table_checksum;
|
||||
UINT32 table_entries;
|
||||
};
|
||||
|
||||
#define CB_SIGNATURE 0x4f49424C // "LBIO"
|
||||
|
||||
struct cb_memory_range {
|
||||
UINT64 start;
|
||||
UINT64 size;
|
||||
UINT32 type;
|
||||
};
|
||||
|
||||
struct cb_memory {
|
||||
UINT32 tag;
|
||||
UINT32 size;
|
||||
struct cb_memory_range map[0];
|
||||
};
|
||||
|
||||
struct cb_forward {
|
||||
UINT32 tag;
|
||||
UINT32 size;
|
||||
UINT64 forward;
|
||||
};
|
||||
|
||||
#define CB_TAG_FORWARD 0x11
|
||||
|
||||
struct cb_cbmem_ref {
|
||||
UINT32 tag;
|
||||
UINT32 size;
|
||||
UINT64 cbmem_addr;
|
||||
};
|
||||
|
||||
#define CB_TAG_CBMEM_CONSOLE 0x17
|
||||
|
||||
struct cbmem_console {
|
||||
UINT32 size;
|
||||
UINT32 cursor;
|
||||
UINT8 body[0];
|
||||
} PACKED;
|
||||
|
||||
#define CBMC_CURSOR_MASK ((1 << 28) - 1)
|
||||
#define CBMC_OVERFLOW (1 << 31)
|
||||
|
||||
static struct cbmem_console *cbcon = NULL;
|
||||
|
||||
static UINT16
|
||||
ipchksum(char *buf, int count)
|
||||
{
|
||||
UINT16 *p = (UINT16*)buf;
|
||||
UINT32 sum = 0;
|
||||
while (count > 1) {
|
||||
sum += *p;
|
||||
p++;
|
||||
count -= 2;
|
||||
}
|
||||
if (count)
|
||||
sum += *(UINT8*)p;
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
return ~sum;
|
||||
}
|
||||
|
||||
// Try to locate the coreboot header in a given address range.
|
||||
static struct cb_header *
|
||||
find_cb_header(UINT64 addr, int len)
|
||||
{
|
||||
UINT64 end = addr + len;
|
||||
for (; addr < end; addr += 16) {
|
||||
struct cb_header *cbh = (void*)addr;
|
||||
if (cbh->signature != CB_SIGNATURE)
|
||||
continue;
|
||||
UINT32 tsize = cbh->table_bytes;
|
||||
if (! tsize)
|
||||
continue;
|
||||
if (ipchksum((void*)addr, sizeof(*cbh)) != 0)
|
||||
continue;
|
||||
if (ipchksum((void*)addr + sizeof(*cbh), tsize)
|
||||
!= cbh->table_checksum)
|
||||
continue;
|
||||
return cbh;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try to find the coreboot memory table in the given coreboot table.
|
||||
void *
|
||||
find_cb_subtable(struct cb_header *cbh, UINT32 tag)
|
||||
{
|
||||
char *tbl = (char *)cbh + sizeof(*cbh);
|
||||
UINT32 count = cbh->table_entries;
|
||||
int i;
|
||||
for (i=0; i<count; i++) {
|
||||
struct cb_memory *cbm = (void*)tbl;
|
||||
tbl += cbm->size;
|
||||
if (cbm->tag == tag)
|
||||
return cbm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct cb_header *
|
||||
find_cb_table(void)
|
||||
{
|
||||
struct cb_header *cbh = find_cb_header(0, 0x1000);
|
||||
if (!cbh)
|
||||
return NULL;
|
||||
struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD);
|
||||
if (cbf) {
|
||||
//dprintf(3, "Found coreboot table forwarder.\n");
|
||||
cbh = find_cb_header(cbf->forward, 0x100);
|
||||
if (!cbh)
|
||||
return NULL;
|
||||
}
|
||||
return cbh;
|
||||
}
|
||||
|
||||
static UINT32 STM_cursor = 0;
|
||||
|
||||
int init_cbcons(void)
|
||||
{
|
||||
struct cb_header *cbh = find_cb_table();
|
||||
|
||||
if (!cbh)
|
||||
goto fail;
|
||||
|
||||
struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE);
|
||||
|
||||
if (cbref) {
|
||||
cbcon = (void*)(UINT64)cbref->cbmem_addr;
|
||||
|
||||
// set the cursor such that the STM console will not overwrite the
|
||||
// coreboot console output
|
||||
STM_cursor = cbcon->cursor & CBMC_CURSOR_MASK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void coreboot_debug_putc(char c)
|
||||
{
|
||||
if (!CONFIG_DEBUG_COREBOOT)
|
||||
return;
|
||||
if (!cbcon)
|
||||
return;
|
||||
|
||||
UINT32 cursor = cbcon->cursor & CBMC_CURSOR_MASK;
|
||||
UINT32 flags = cbcon->cursor & ~CBMC_CURSOR_MASK;
|
||||
|
||||
if (cursor >= cbcon->size)
|
||||
return; // Old coreboot version with legacy overflow mechanism.
|
||||
|
||||
cbcon->body[cursor++] = c;
|
||||
if (cursor >= cbcon->size) {
|
||||
cursor = STM_cursor;
|
||||
flags |= CBMC_OVERFLOW;
|
||||
}
|
||||
cbcon->cursor = flags | cursor;
|
||||
}
|
||||
|
Loading…
Reference in New Issue