drivers/elog/elog.c: Drop CAR_GLOBAL_MIGRATION support

Change-Id: I7dcc8d08b40560f105c22454bda1282afaa617da
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37046
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Arthur Heymans 2019-11-20 22:06:47 +01:00 committed by Patrick Georgi
parent 7c2994bb73
commit 2d33c3e6c3
1 changed files with 43 additions and 84 deletions

View File

@ -14,7 +14,6 @@
#if CONFIG(HAVE_ACPI_RESUME) #if CONFIG(HAVE_ACPI_RESUME)
#include <arch/acpi.h> #include <arch/acpi.h>
#endif #endif
#include <arch/early_variables.h>
#include <bootstate.h> #include <bootstate.h>
#include <cbmem.h> #include <cbmem.h>
#include <console/console.h> #include <console/console.h>
@ -66,21 +65,14 @@ struct elog_state {
enum elog_init_state elog_initialized; enum elog_init_state elog_initialized;
}; };
static struct elog_state g_elog_state CAR_GLOBAL; static struct elog_state g_elog_state;
#define ELOG_SIZE (4 * KiB) #define ELOG_SIZE (4 * KiB)
static uint8_t elog_mirror_buf[ELOG_SIZE] CAR_GLOBAL; static uint8_t elog_mirror_buf[ELOG_SIZE];
static void *get_elog_mirror_buffer(void)
{
return car_get_var_ptr(elog_mirror_buf);
}
static inline struct region_device *mirror_dev_get(void) static inline struct region_device *mirror_dev_get(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); return &g_elog_state.mirror_dev.rdev;
return &es->mirror_dev.rdev;
} }
static size_t elog_events_start(void) static size_t elog_events_start(void)
@ -91,9 +83,7 @@ static size_t elog_events_start(void)
static size_t elog_events_total_space(void) static size_t elog_events_total_space(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); return region_device_sz(&g_elog_state.nv_dev) - elog_events_start();
return region_device_sz(&es->nv_dev) - elog_events_start();
} }
static struct event_header *elog_get_event_buffer(size_t offset, size_t size) static struct event_header *elog_get_event_buffer(size_t offset, size_t size)
@ -103,10 +93,8 @@ static struct event_header *elog_get_event_buffer(size_t offset, size_t size)
static struct event_header *elog_get_next_event_buffer(size_t size) static struct event_header *elog_get_next_event_buffer(size_t size)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); elog_debug("ELOG: new event at offset 0x%zx\n", g_elog_state.mirror_last_write);
return elog_get_event_buffer(g_elog_state.mirror_last_write, size);
elog_debug("ELOG: new event at offset 0x%zx\n", es->mirror_last_write);
return elog_get_event_buffer(es->mirror_last_write, size);
} }
static void elog_put_event_buffer(struct event_header *event) static void elog_put_event_buffer(struct event_header *event)
@ -116,71 +104,54 @@ static void elog_put_event_buffer(struct event_header *event)
static size_t elog_mirror_reset_last_write(void) static size_t elog_mirror_reset_last_write(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state);
/* Return previous write value. */ /* Return previous write value. */
size_t prev = es->mirror_last_write; size_t prev = g_elog_state.mirror_last_write;
es->mirror_last_write = 0; g_elog_state.mirror_last_write = 0;
return prev; return prev;
} }
static void elog_mirror_increment_last_write(size_t size) static void elog_mirror_increment_last_write(size_t size)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); g_elog_state.mirror_last_write += size;
es->mirror_last_write += size;
} }
static void elog_nv_reset_last_write(void) static void elog_nv_reset_last_write(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); g_elog_state.nv_last_write = 0;
es->nv_last_write = 0;
} }
static void elog_nv_increment_last_write(size_t size) static void elog_nv_increment_last_write(size_t size)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); g_elog_state.nv_last_write += size;
es->nv_last_write += size;
} }
static void elog_nv_needs_possible_erase(void) static void elog_nv_needs_possible_erase(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state);
/* If last write is 0 it means it is already erased. */ /* If last write is 0 it means it is already erased. */
if (es->nv_last_write != 0) if (g_elog_state.nv_last_write != 0)
es->nv_last_write = NV_NEEDS_ERASE; g_elog_state.nv_last_write = NV_NEEDS_ERASE;
} }
static bool elog_should_shrink(void) static bool elog_should_shrink(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); return g_elog_state.mirror_last_write >= g_elog_state.full_threshold;
return es->mirror_last_write >= es->full_threshold;
} }
static bool elog_nv_needs_erase(void) static bool elog_nv_needs_erase(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); return g_elog_state.nv_last_write == NV_NEEDS_ERASE;
return es->nv_last_write == NV_NEEDS_ERASE;
} }
static bool elog_nv_needs_update(void) static bool elog_nv_needs_update(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); return g_elog_state.nv_last_write != g_elog_state.mirror_last_write;
return es->nv_last_write != es->mirror_last_write;
} }
static size_t elog_nv_region_to_update(size_t *offset) static size_t elog_nv_region_to_update(size_t *offset)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); *offset = g_elog_state.nv_last_write;
return g_elog_state.mirror_last_write - g_elog_state.nv_last_write;
*offset = es->nv_last_write;
return es->mirror_last_write - es->nv_last_write;
} }
/* /*
@ -352,8 +323,6 @@ static void elog_nv_write(size_t offset, size_t size)
{ {
void *address; void *address;
const struct region_device *rdev = mirror_dev_get(); const struct region_device *rdev = mirror_dev_get();
struct elog_state *es = car_get_var_ptr(&g_elog_state);
if (!size) if (!size)
return; return;
@ -366,7 +335,7 @@ static void elog_nv_write(size_t offset, size_t size)
return; return;
/* Write the data to flash */ /* Write the data to flash */
if (rdev_writeat(&es->nv_dev, address, offset, size) != size) if (rdev_writeat(&g_elog_state.nv_dev, address, offset, size) != size)
printk(BIOS_ERR, "ELOG: NV Write failed at 0x%zx, size 0x%zx\n", printk(BIOS_ERR, "ELOG: NV Write failed at 0x%zx, size 0x%zx\n",
offset, size); offset, size);
@ -379,12 +348,11 @@ static void elog_nv_write(size_t offset, size_t size)
*/ */
static void elog_nv_erase(void) static void elog_nv_erase(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state); size_t size = region_device_sz(&g_elog_state.nv_dev);
size_t size = region_device_sz(&es->nv_dev);
elog_debug("%s()\n", __func__); elog_debug("%s()\n", __func__);
/* Erase the sectors in this region */ /* Erase the sectors in this region */
if (rdev_eraseat(&es->nv_dev, 0, size) != size) if (rdev_eraseat(&g_elog_state.nv_dev, 0, size) != size)
printk(BIOS_ERR, "ELOG: erase failure.\n"); printk(BIOS_ERR, "ELOG: erase failure.\n");
} }
@ -442,12 +410,12 @@ static int elog_scan_flash(void)
elog_debug("elog_scan_flash()\n"); elog_debug("elog_scan_flash()\n");
void *mirror_buffer; void *mirror_buffer;
const struct region_device *rdev = mirror_dev_get(); const struct region_device *rdev = mirror_dev_get();
struct elog_state *es = car_get_var_ptr(&g_elog_state);
size_t size = region_device_sz(&es->nv_dev); size_t size = region_device_sz(&g_elog_state.nv_dev);
/* Fill memory buffer by reading from SPI */ /* Fill memory buffer by reading from SPI */
mirror_buffer = rdev_mmap_full(rdev); mirror_buffer = rdev_mmap_full(rdev);
if (rdev_readat(&es->nv_dev, mirror_buffer, 0, size) != size) { if (rdev_readat(&g_elog_state.nv_dev, mirror_buffer, 0, size) != size) {
rdev_munmap(rdev, mirror_buffer); rdev_munmap(rdev, mirror_buffer);
printk(BIOS_ERR, "ELOG: NV read failure.\n"); printk(BIOS_ERR, "ELOG: NV read failure.\n");
return -1; return -1;
@ -611,10 +579,8 @@ static int elog_prepare_empty(void)
static int elog_shrink(void) static int elog_shrink(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state);
if (elog_should_shrink()) if (elog_should_shrink())
return elog_shrink_by_size(es->shrink_size); return elog_shrink_by_size(g_elog_state.shrink_size);
return 0; return 0;
} }
@ -623,18 +589,16 @@ static int elog_shrink(void)
*/ */
static inline u8 *elog_flash_offset_to_address(void) static inline u8 *elog_flash_offset_to_address(void)
{ {
struct elog_state *es = car_get_var_ptr(&g_elog_state);
/* Only support memory-mapped devices. */ /* Only support memory-mapped devices. */
if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED)) if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED))
return NULL; return NULL;
if (!region_device_sz(&es->nv_dev)) if (!region_device_sz(&g_elog_state.nv_dev))
return NULL; return NULL;
/* Get a view into the read-only boot device. */ /* Get a view into the read-only boot device. */
return rdev_mmap(boot_device_ro(), region_device_offset(&es->nv_dev), return rdev_mmap(boot_device_ro(), region_device_offset(&g_elog_state.nv_dev),
region_device_sz(&es->nv_dev)); region_device_sz(&g_elog_state.nv_dev));
} }
/* /*
@ -646,8 +610,8 @@ int elog_smbios_write_type15(unsigned long *current, int handle)
struct smbios_type15 *t = (struct smbios_type15 *)*current; struct smbios_type15 *t = (struct smbios_type15 *)*current;
int len = sizeof(struct smbios_type15); int len = sizeof(struct smbios_type15);
uintptr_t log_address; uintptr_t log_address;
struct elog_state *es = car_get_var_ptr(&g_elog_state);
size_t elog_size = region_device_sz(&es->nv_dev); size_t elog_size = region_device_sz(&g_elog_state.nv_dev);
if (CONFIG(ELOG_CBMEM)) { if (CONFIG(ELOG_CBMEM)) {
/* Save event log buffer into CBMEM for the OS to read */ /* Save event log buffer into CBMEM for the OS to read */
@ -701,8 +665,7 @@ static int elog_find_flash(void)
{ {
size_t total_size; size_t total_size;
size_t reserved_space = ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE; size_t reserved_space = ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE;
struct elog_state *es = car_get_var_ptr(&g_elog_state); struct region_device *rdev = &g_elog_state.nv_dev;
struct region_device *rdev = &es->nv_dev;
elog_debug("%s()\n", __func__); elog_debug("%s()\n", __func__);
@ -725,10 +688,10 @@ static int elog_find_flash(void)
total_size = MIN(ELOG_SIZE, region_device_sz(rdev)); total_size = MIN(ELOG_SIZE, region_device_sz(rdev));
rdev_chain(rdev, rdev, 0, total_size); rdev_chain(rdev, rdev, 0, total_size);
es->full_threshold = total_size - reserved_space; g_elog_state.full_threshold = total_size - reserved_space;
es->shrink_size = total_size * ELOG_SHRINK_PERCENTAGE / 100; g_elog_state.shrink_size = total_size * ELOG_SHRINK_PERCENTAGE / 100;
if (reserved_space > es->shrink_size) { if (reserved_space > g_elog_state.shrink_size) {
printk(BIOS_ERR, "ELOG: SHRINK_PERCENTAGE too small\n"); printk(BIOS_ERR, "ELOG: SHRINK_PERCENTAGE too small\n");
return -1; return -1;
} }
@ -741,8 +704,6 @@ static int elog_sync_to_nv(void)
size_t offset; size_t offset;
size_t size; size_t size;
bool erase_needed; bool erase_needed;
struct elog_state *es = car_get_var_ptr(&g_elog_state);
/* Determine if any updates are required. */ /* Determine if any updates are required. */
if (!elog_nv_needs_update()) if (!elog_nv_needs_update())
return 0; return 0;
@ -773,7 +734,7 @@ static int elog_sync_to_nv(void)
if (elog_scan_flash() < 0) { if (elog_scan_flash() < 0) {
printk(BIOS_ERR, "ELOG: Sync back from NV storage failed.\n"); printk(BIOS_ERR, "ELOG: Sync back from NV storage failed.\n");
elog_debug_dump_buffer("ELOG: Buffer from NV:\n"); elog_debug_dump_buffer("ELOG: Buffer from NV:\n");
es->elog_initialized = ELOG_BROKEN; g_elog_state.elog_initialized = ELOG_BROKEN;
return -1; return -1;
} }
@ -815,9 +776,7 @@ int elog_init(void)
{ {
void *mirror_buffer; void *mirror_buffer;
size_t elog_size; size_t elog_size;
struct elog_state *es = car_get_var_ptr(&g_elog_state); switch (g_elog_state.elog_initialized) {
switch (es->elog_initialized) {
case ELOG_UNINITIALIZED: case ELOG_UNINITIALIZED:
break; break;
case ELOG_INITIALIZED: case ELOG_INITIALIZED:
@ -825,7 +784,7 @@ int elog_init(void)
case ELOG_BROKEN: case ELOG_BROKEN:
return -1; return -1;
} }
es->elog_initialized = ELOG_BROKEN; g_elog_state.elog_initialized = ELOG_BROKEN;
elog_debug("elog_init()\n"); elog_debug("elog_init()\n");
@ -833,19 +792,19 @@ int elog_init(void)
if (elog_find_flash() < 0) if (elog_find_flash() < 0)
return -1; return -1;
elog_size = region_device_sz(&es->nv_dev); elog_size = region_device_sz(&g_elog_state.nv_dev);
mirror_buffer = get_elog_mirror_buffer(); mirror_buffer = elog_mirror_buf;
if (!mirror_buffer) { if (!mirror_buffer) {
printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n"); printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n");
return -1; return -1;
} }
mem_region_device_rw_init(&es->mirror_dev, mirror_buffer, elog_size); mem_region_device_rw_init(&g_elog_state.mirror_dev, mirror_buffer, elog_size);
/* /*
* Mark as initialized to allow elog_init() to be called and deemed * Mark as initialized to allow elog_init() to be called and deemed
* successful in the prepare/shrink path which adds events. * successful in the prepare/shrink path which adds events.
*/ */
es->elog_initialized = ELOG_INITIALIZED; g_elog_state.elog_initialized = ELOG_INITIALIZED;
/* Load the log from flash and prepare the flash if necessary. */ /* Load the log from flash and prepare the flash if necessary. */
if (elog_scan_flash() < 0 && elog_prepare_empty() < 0) { if (elog_scan_flash() < 0 && elog_prepare_empty() < 0) {
@ -854,8 +813,8 @@ int elog_init(void)
} }
printk(BIOS_INFO, "ELOG: area is %zu bytes, full threshold %d," printk(BIOS_INFO, "ELOG: area is %zu bytes, full threshold %d,"
" shrink size %d\n", region_device_sz(&es->nv_dev), " shrink size %d\n", region_device_sz(&g_elog_state.nv_dev),
es->full_threshold, es->shrink_size); g_elog_state.full_threshold, g_elog_state.shrink_size);
if (ENV_PAYLOAD_LOADER) if (ENV_PAYLOAD_LOADER)
elog_add_boot_count(); elog_add_boot_count();