ELOG: Add support for generating SMBIOS type15 table

This standared SMBIOS 0able describes the location and format
of the event log to the OS and applications.  In this case the
pointer is a 32bit physical address pointer to the log in
memory mapped flash.

Look for SMBIOS type15 entry with 'dmidecode -t 15'

Handle 0x0004, DMI type 15, 23 bytes
System Event Log
        Area Length: 4095 bytes
        Header Start Offset: 0x0000
        Header Length: 8 bytes
        Data Start Offset: 0x0008
        Access Method: Memory-mapped physical 32-bit address
        Access Address: 0xFFB6F000
        Status: Valid, Not Full
        Change Token: 0x00000000
        Header Format: OEM-specific
        Supported Log Type Descriptors: 0

Change-Id: I1e7729e604000f197e26e69991a2867e869197a6
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/1314
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Duncan Laurie 2012-06-23 16:13:42 -07:00 committed by Ronald G. Minnich
parent 696262bd99
commit 472ec9cd7e
5 changed files with 80 additions and 0 deletions

View File

@ -29,6 +29,7 @@
#include <cpu/x86/name.h> #include <cpu/x86/name.h>
#include <cbfs_core.h> #include <cbfs_core.h>
#include <arch/byteorder.h> #include <arch/byteorder.h>
#include <elog.h>
#if CONFIG_CHROMEOS #if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/gnvs.h> #include <vendorcode/google/chromeos/gnvs.h>
#endif #endif
@ -296,6 +297,9 @@ unsigned long smbios_write_tables(unsigned long current)
len += smbios_write_type1(&current, handle++); len += smbios_write_type1(&current, handle++);
len += smbios_write_type3(&current, handle++); len += smbios_write_type3(&current, handle++);
len += smbios_write_type4(&current, handle++); len += smbios_write_type4(&current, handle++);
#if CONFIG_ELOG
len += elog_smbios_write_type15(&current, handle++);
#endif
len += smbios_write_type32(&current, handle++); len += smbios_write_type32(&current, handle++);
len += smbios_walk_device_tree(all_devices, &handle, &current); len += smbios_walk_device_tree(all_devices, &handle, &current);

View File

@ -20,6 +20,7 @@
#include <arch/acpi.h> #include <arch/acpi.h>
#include <console/console.h> #include <console/console.h>
#include <pc80/mc146818rtc.h> #include <pc80/mc146818rtc.h>
#include <smbios.h>
#include <spi.h> #include <spi.h>
#include <spi_flash.h> #include <spi_flash.h>
#include <stdint.h> #include <stdint.h>
@ -676,6 +677,34 @@ static int elog_spi_init(void)
return elog_spi ? 0 : -1; return elog_spi ? 0 : -1;
} }
/*
* Fill out SMBIOS Type 15 table entry so the
* event log can be discovered at runtime.
*/
int elog_smbios_write_type15(unsigned long *current, int handle)
{
struct smbios_type15 *t = (struct smbios_type15 *)*current;
int len = sizeof(struct smbios_type15);
memset(t, 0, len);
t->type = SMBIOS_EVENT_LOG;
t->length = len - 2;
t->handle = handle;
t->area_length = elog_get_flash()->total_size - 1;
t->header_offset = 0;
t->data_offset = sizeof(struct elog_header);
t->access_method = SMBIOS_EVENTLOG_ACCESS_METHOD_MMIO32;
t->log_status = SMBIOS_EVENTLOG_STATUS_VALID;
t->change_token = 0;
t->address = (u32)elog_get_flash()->backing_store;
t->header_format = ELOG_HEADER_TYPE_OEM;
t->log_type_descriptors = 0;
t->log_type_descriptor_length = 2;
*current += len;
return len;
}
/* /*
* Clear the entire event log * Clear the entire event log
*/ */

View File

@ -32,6 +32,21 @@ struct elog_header {
#define ELOG_SIGNATURE 0x474f4c45 /* 'ELOG' */ #define ELOG_SIGNATURE 0x474f4c45 /* 'ELOG' */
#define ELOG_VERSION 1 #define ELOG_VERSION 1
/* SMBIOS event log header */
struct event_header {
u8 type;
u8 length;
u8 year;
u8 month;
u8 day;
u8 hour;
u8 minute;
u8 second;
} __attribute__ ((packed));
/* SMBIOS Type 15 related constants */
#define ELOG_HEADER_TYPE_OEM 0x88
typedef enum elog_descriptor_type { typedef enum elog_descriptor_type {
ELOG_DESCRIPTOR_UNKNOWN, ELOG_DESCRIPTOR_UNKNOWN,
ELOG_DESCRIPTOR_MEMORY, ELOG_DESCRIPTOR_MEMORY,

View File

@ -113,6 +113,7 @@ extern void elog_add_event_byte(u8 event_type, u8 data);
extern void elog_add_event_word(u8 event_type, u16 data); extern void elog_add_event_word(u8 event_type, u16 data);
extern void elog_add_event_dword(u8 event_type, u32 data); extern void elog_add_event_dword(u8 event_type, u32 data);
extern void elog_add_event_wake(u8 source, u32 instance); extern void elog_add_event_wake(u8 source, u32 instance);
extern int elog_smbios_write_type15(unsigned long *current, int handle);
#endif /* !CONFIG_ELOG */ #endif /* !CONFIG_ELOG */

View File

@ -28,6 +28,7 @@ typedef enum {
SMBIOS_PROCESSOR_INFORMATION=4, SMBIOS_PROCESSOR_INFORMATION=4,
SMBIOS_CACHE_INFORMATION=7, SMBIOS_CACHE_INFORMATION=7,
SMBIOS_SYSTEM_SLOTS=9, SMBIOS_SYSTEM_SLOTS=9,
SMBIOS_EVENT_LOG=15,
SMBIOS_PHYS_MEMORY_ARRAY=16, SMBIOS_PHYS_MEMORY_ARRAY=16,
SMBIOS_MEMORY_DEVICE=17, SMBIOS_MEMORY_DEVICE=17,
SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS=19, SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS=19,
@ -138,6 +139,36 @@ struct smbios_type4 {
char eos[2]; char eos[2];
} __attribute__((packed)); } __attribute__((packed));
struct smbios_type15 {
u8 type;
u8 length;
u16 handle;
u16 area_length;
u16 header_offset;
u16 data_offset;
u8 access_method;
u8 log_status;
u32 change_token;
u32 address;
u8 header_format;
u8 log_type_descriptors;
u8 log_type_descriptor_length;
char eos[2];
} __attribute__((packed));
enum {
SMBIOS_EVENTLOG_ACCESS_METHOD_IO8 = 0,
SMBIOS_EVENTLOG_ACCESS_METHOD_IO8X2,
SMBIOS_EVENTLOG_ACCESS_METHOD_IO16,
SMBIOS_EVENTLOG_ACCESS_METHOD_MMIO32,
SMBIOS_EVENTLOG_ACCESS_METHOD_GPNV,
};
enum {
SMBIOS_EVENTLOG_STATUS_VALID = 1, /* Bit 0 */
SMBIOS_EVENTLOG_STATUS_FULL = 2, /* Bit 1 */
};
struct smbios_type16 { struct smbios_type16 {
u8 type; u8 type;
u8 length; u8 length;