summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0027-src-console-Add-x86-romstage-spinlock-option-and-pri.patch
blob: a2aa4387f0ab14140f69c8578eee6e903de817c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
From 27f6bb783ba638e6aa2539a6c51ec96386dbf28f Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Mon, 18 May 2015 16:04:10 -0500
Subject: [PATCH 027/143] src/console: Add x86 romstage spinlock option and
 prink spinlock support

Change-Id: Ice42a0d3177736bf6e1bc601092e413601866f20
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/Kconfig                              |    4 ++++
 src/arch/x86/include/arch/smp/spinlock.h |   11 ++++++++++-
 src/console/printk.c                     |   19 +++++++++++++++++++
 src/cpu/amd/car/disable_cache_as_ram.c   |   10 ++++++++++
 src/cpu/amd/car/post_cache_as_ram.c      |   20 ++++++++++++++------
 5 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 368384d..5aa33d00 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -446,6 +446,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 32be2f2..3283540 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__) || defined(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 aab7ff5..5a23db0 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,13 @@
 #include <stddef.h>
 #include <trace.h>
 
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+#ifndef __PRE_RAM__
 DECLARE_SPIN_LOCK(console_lock)
+#endif
+#else
+DECLARE_SPIN_LOCK(console_lock)
+#endif
 
 void do_putchar(unsigned char byte)
 {
@@ -39,7 +46,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 +60,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/disable_cache_as_ram.c b/src/cpu/amd/car/disable_cache_as_ram.c
index 3b464b8..5eccf79 100644
--- a/src/cpu/amd/car/disable_cache_as_ram.c
+++ b/src/cpu/amd/car/disable_cache_as_ram.c
@@ -24,6 +24,16 @@
 
 #include <cpu/x86/cache.h>
 
+static inline __attribute__((always_inline)) uint32_t amd_fam1x_cpu_family(void)
+{
+	uint32_t family;
+
+	family = cpuid_eax(0x80000001);
+	family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
+
+	return family;
+}
+
 static inline __attribute__((always_inline)) void disable_cache_as_ram(void)
 {
 	msr_t msr;
diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c
index e265de1..257b41a 100644
--- a/src/cpu/amd/car/post_cache_as_ram.c
+++ b/src/cpu/amd/car/post_cache_as_ram.c
@@ -84,6 +84,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");
 }
 
@@ -92,18 +96,19 @@ static void prepare_ramstage_region(void *resume_backup_memory)
 static void vErrata343(void)
 {
 #ifdef BU_CFG2_MSR
-    msr_t msr;
-    unsigned int uiMask = 0xFFFFFFF7;
+	msr_t msr;
+	unsigned int uiMask = 0xFFFFFFF7;
 
-    msr = rdmsr(BU_CFG2_MSR);
-    msr.hi &= uiMask; // set bit 35 to 0
-    wrmsr(BU_CFG2_MSR, msr);
+	msr = rdmsr(BU_CFG2_MSR);
+	msr.hi &= uiMask;	// IcDisSpecTlbWr (bit 35) = 0
+	wrmsr(BU_CFG2_MSR, msr);
 #endif
 }
 
 void post_cache_as_ram(void)
 {
 	void *resume_backup_memory = NULL;
+	uint32_t family = amd_fam1x_cpu_family();
 
 	struct romstage_handoff *handoff;
 	handoff = romstage_handoff_find_or_add();
@@ -120,7 +125,10 @@ void post_cache_as_ram(void)
 	prepare_romstage_ramstack(resume_backup_memory);
 
 	/* from here don't store more data in CAR */
-	vErrata343();
+	if (family < 0x6f) {
+		/* Family 10h or earlier */
+		vErrata343();
+	}
 
 	size_t car_size = car_data_size();
 	void *migrated_car = (void *)(CONFIG_RAMTOP - car_size);
-- 
1.7.9.5