diff options
-rw-r--r-- | src/Kconfig | 8 | ||||
-rw-r--r-- | src/arch/x86/include/arch/smp/spinlock.h | 4 | ||||
-rw-r--r-- | src/cpu/amd/car/post_cache_as_ram.c | 3 | ||||
-rw-r--r-- | src/drivers/pc80/mc146818rtc.c | 25 |
4 files changed, 37 insertions, 3 deletions
diff --git a/src/Kconfig b/src/Kconfig index 6fbc1f0b10..38cf855cc8 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -480,6 +480,14 @@ config HAVE_ROMSTAGE_CONSOLE_SPINLOCK bool default n +config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK + bool + default n + help + This should be enabled on certain plaforms, such as the AMD + SR565x, that cannot handle concurrent CBFS accesses from + multiple APs during early startup. + config HAVE_MONOTONIC_TIMER def_bool n help diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h index 74e532c68a..057d9e3f8f 100644 --- a/src/arch/x86/include/arch/smp/spinlock.h +++ b/src/arch/x86/include/arch/smp/spinlock.h @@ -1,7 +1,7 @@ #ifndef ARCH_SMP_SPINLOCK_H #define ARCH_SMP_SPINLOCK_H -#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) +#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) /* * Your basic SMP spinlocks, allowing only a single CPU anywhere @@ -14,6 +14,8 @@ typedef struct { #ifdef __PRE_RAM__ spinlock_t *romstage_console_lock(void); void initialize_romstage_console_lock(void); +spinlock_t* romstage_nvram_cbfs_lock(void); +void initialize_romstage_nvram_cbfs_lock(void); #endif #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c index 8c5757e209..435fdcb588 100644 --- a/src/cpu/amd/car/post_cache_as_ram.c +++ b/src/cpu/amd/car/post_cache_as_ram.c @@ -79,6 +79,9 @@ static void prepare_ramstage_region(void *resume_backup_memory) #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) initialize_romstage_console_lock(); #endif +#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) + initialize_romstage_nvram_cbfs_lock(); +#endif print_car_debug(" Done\n"); } diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c index 0c95265c61..6c39f812b9 100644 --- a/src/drivers/pc80/mc146818rtc.c +++ b/src/drivers/pc80/mc146818rtc.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright 2014 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +34,16 @@ #define LB_CKS_LOC 0 #endif +#include <smp/spinlock.h> + +#if (defined(__PRE_RAM__) && \ +IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)) + #define LOCK_NVRAM_CBFS_SPINLOCK spin_lock(romstage_nvram_cbfs_lock()); + #define UNLOCK_NVRAM_CBFS_SPINLOCK spin_unlock(romstage_nvram_cbfs_lock()); +#else + #define LOCK_NVRAM_CBFS_SPINLOCK + #define UNLOCK_NVRAM_CBFS_SPINLOCK +#endif static void cmos_reset_date(void) { @@ -204,6 +215,8 @@ enum cb_err get_option(void *dest, const char *name) if (!IS_ENABLED(CONFIG_USE_OPTION_TABLE)) return CB_CMOS_OTABLE_DISABLED; + LOCK_NVRAM_CBFS_SPINLOCK + /* Figure out how long name is */ namelen = strnlen(name, CMOS_MAX_NAME_LENGTH); @@ -213,6 +226,8 @@ enum cb_err get_option(void *dest, const char *name) if (!ct) { printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. " "Options are disabled\n"); + + UNLOCK_NVRAM_CBFS_SPINLOCK return CB_CMOS_LAYOUT_NOT_FOUND; } ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length); @@ -225,13 +240,19 @@ enum cb_err get_option(void *dest, const char *name) } if (!found) { printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name); + UNLOCK_NVRAM_CBFS_SPINLOCK return CB_CMOS_OPTION_NOT_FOUND; } - if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS) + if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS) { + UNLOCK_NVRAM_CBFS_SPINLOCK return CB_CMOS_ACCESS_ERROR; - if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC)) + } + if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC)) { + UNLOCK_NVRAM_CBFS_SPINLOCK return CB_CMOS_CHECKSUM_INVALID; + } + UNLOCK_NVRAM_CBFS_SPINLOCK return CB_SUCCESS; } |