aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig8
-rw-r--r--src/arch/x86/include/arch/smp/spinlock.h4
-rw-r--r--src/cpu/amd/car/post_cache_as_ram.c3
-rw-r--r--src/drivers/pc80/mc146818rtc.c25
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;
}