summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-05-18 16:04:10 -0500
committerMartin Roth <martinroth@google.com>2015-12-15 16:41:13 +0100
commit44d53428352ff5d6c8941160429735b5465add5f (patch)
tree8b902553c7a507fd8ad303e45a19b70b1887eed1
parenta09bb426d4149506c8cc588704cb5d8136f9c3f9 (diff)
downloadcoreboot-44d53428352ff5d6c8941160429735b5465add5f.tar.xz
src/console: Add x86 romstage spinlock option and printk spinlock support
This paves the way for AP printk spinlock on AMD platforms Change-Id: Ice42a0d3177736bf6e1bc601092e413601866f20 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: https://review.coreboot.org/11958 Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
-rw-r--r--src/Kconfig4
-rw-r--r--src/arch/x86/include/arch/smp/spinlock.h11
-rw-r--r--src/console/printk.c15
-rw-r--r--src/cpu/amd/car/post_cache_as_ram.c4
4 files changed, 33 insertions, 1 deletions
diff --git a/src/Kconfig b/src/Kconfig
index 818eb59c8b..46349c5f99 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -476,6 +476,10 @@ config HAVE_HARD_RESET
This variable specifies whether a given board has a hard_reset
function, no matter if it's provided by board code or chipset code.
+config HAVE_ROMSTAGE_CONSOLE_SPINLOCK
+ bool
+ default n
+
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 32be2f25fb..74e532c68a 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
-#ifndef __PRE_RAM__
+#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
@@ -11,9 +11,18 @@ typedef struct {
volatile unsigned int lock;
} spinlock_t;
+#ifdef __PRE_RAM__
+spinlock_t *romstage_console_lock(void);
+void initialize_romstage_console_lock(void);
+#endif
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+
+#ifndef __PRE_RAM__
#define DECLARE_SPIN_LOCK(x) static spinlock_t x = SPIN_LOCK_UNLOCKED;
+#else
+#define DECLARE_SPIN_LOCK(x)
+#endif
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
diff --git a/src/console/printk.c b/src/console/printk.c
index aab7ff5f67..99f90a8e28 100644
--- a/src/console/printk.c
+++ b/src/console/printk.c
@@ -2,6 +2,7 @@
* blatantly copied from linux/kernel/printk.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
*
*/
@@ -13,7 +14,9 @@
#include <stddef.h>
#include <trace.h>
+#if (!defined(__PRE_RAM__) && IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)) || !IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
DECLARE_SPIN_LOCK(console_lock)
+#endif
void do_putchar(unsigned char byte)
{
@@ -39,7 +42,13 @@ int do_printk(int msg_level, const char *fmt, ...)
#endif
DISABLE_TRACE;
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+ spin_lock(romstage_console_lock());
+#endif
+#else
spin_lock(&console_lock);
+#endif
va_start(args, fmt);
i = vtxprintf(wrap_putchar, fmt, args, NULL);
@@ -47,7 +56,13 @@ int do_printk(int msg_level, const char *fmt, ...)
console_tx_flush();
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+ spin_unlock(romstage_console_lock());
+#endif
+#else
spin_unlock(&console_lock);
+#endif
ENABLE_TRACE;
return i;
diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c
index fb09cd41dd..8c5757e209 100644
--- a/src/cpu/amd/car/post_cache_as_ram.c
+++ b/src/cpu/amd/car/post_cache_as_ram.c
@@ -76,6 +76,10 @@ static void prepare_ramstage_region(void *resume_backup_memory)
memset_((void*)0, 0, CONFIG_RAMTOP - backup_top);
}
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+ initialize_romstage_console_lock();
+#endif
+
print_car_debug(" Done\n");
}