summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/kgpe-d16/0132-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch
blob: 26605657bb55bcd7b28a8aa6158ae627edbab7e6 (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
From 150c1d37f6b42233ae47a9289563164b8685825a Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Fri, 28 Aug 2015 20:48:17 -0500
Subject: [PATCH 132/143] cpu/amd/microcode: Introduce CBFS access spinlock to
 avoid IOMMU failure

Change-Id: Ib7e8cb171f44833167053ca98a85cca23021dfba
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 src/Kconfig                              |    4 ++++
 src/arch/x86/include/arch/smp/spinlock.h |    7 ++++++-
 src/cpu/amd/microcode/microcode.c        |   24 +++++++++++++++++++++++-
 src/mainboard/asus/kgpe-d16/Kconfig      |    1 +
 src/mainboard/asus/kgpe-d16/romstage.c   |   15 ++++++++++++++-
 5 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 70f3cf2..353eede 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -454,6 +454,10 @@ config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
 	bool
 	default n
 
+config HAVE_ROMSTAGE_MICROCODE_CBFS_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 74f8ece..a9dcfcd 100644
--- a/src/arch/x86/include/arch/smp/spinlock.h
+++ b/src/arch/x86/include/arch/smp/spinlock.h
@@ -1,7 +1,10 @@
 #ifndef ARCH_SMP_SPINLOCK_H
 #define ARCH_SMP_SPINLOCK_H
 
-#if !defined(__PRE_RAM__) || defined(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || defined(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
+#if !defined(__PRE_RAM__) \
+	|| defined(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)	\
+	|| defined(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)	\
+	|| defined(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
 
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
@@ -16,6 +19,8 @@ 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);
+spinlock_t* romstage_microcode_cbfs_lock(void);
+void initialize_romstage_microcode_cbfs_lock(void);
 #endif
 
 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c
index badd3b7..bf644ab 100644
--- a/src/cpu/amd/microcode/microcode.c
+++ b/src/cpu/amd/microcode/microcode.c
@@ -25,6 +25,12 @@
 #include <cbfs.h>
 #include <arch/io.h>
 
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
+#include <smp/spinlock.h>
+#endif
+#endif
+
 #define UCODE_DEBUG(fmt, args...)	\
 	do { printk(BIOS_DEBUG, "[microcode] "fmt, ##args); } while(0)
 
@@ -201,14 +207,30 @@ void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id)
 			return;
 		}
 
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
+		spin_lock(romstage_microcode_cbfs_lock());
+#endif
+#endif
+
 		ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i],
 						CBFS_TYPE_MICROCODE, &ucode_len);
 		if (!ucode) {
 			UCODE_DEBUG("microcode file not found. Skipping updates.\n");
-
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
+			spin_unlock(romstage_microcode_cbfs_lock());
+#endif
+#endif
 			return;
 		}
 
 		amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);
+
+#ifdef __PRE_RAM__
+#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
+		spin_unlock(romstage_microcode_cbfs_lock());
+#endif
+#endif
 	}
 }
diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
index a9261f9..ff9afd3 100644
--- a/src/mainboard/asus/kgpe-d16/Kconfig
+++ b/src/mainboard/asus/kgpe-d16/Kconfig
@@ -16,6 +16,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	select PARALLEL_CPU_INIT
 	select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
 	select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
+	select HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK
 	select HAVE_HARD_RESET
 	select HAVE_OPTION_TABLE
 	select HAVE_CMOS_DEFAULT
diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
index 9998359..d1b75b6 100644
--- a/src/mainboard/asus/kgpe-d16/romstage.c
+++ b/src/mainboard/asus/kgpe-d16/romstage.c
@@ -327,6 +327,18 @@ void initialize_romstage_nvram_cbfs_lock(void)
 	car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED;
 }
 
+static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL;
+
+spinlock_t* romstage_microcode_cbfs_lock(void)
+{
+	return car_get_var_ptr(&microcode_cbfs_spinlock);
+}
+
+void initialize_romstage_microcode_cbfs_lock(void)
+{
+	car_get_var(microcode_cbfs_spinlock) = SPIN_LOCK_UNLOCKED;
+}
+
 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
 {
 	uint32_t esp;
@@ -348,9 +360,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
 		timestamp_init(timestamp_get());
 		timestamp_add_now(TS_START_ROMSTAGE);
 
-		/* Initialize the printk and nvram CBFS spinlocks */
+		/* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */
 		initialize_romstage_console_lock();
 		initialize_romstage_nvram_cbfs_lock();
+		initialize_romstage_microcode_cbfs_lock();
 
 		/* Nothing special needs to be done to find bus 0 */
 		/* Allow the HT devices to be found */
-- 
1.7.9.5