aboutsummaryrefslogtreecommitdiff
path: root/resources/libreboot/patch/kgpe-d16/0132-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch
blob: a8005e8a4afed10354c99278f637ac83fabcb62d (plain) (blame)
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
From 2b8c4a3914e4d0705f10f09ea570e6f8a9d7ef93 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Fri, 28 Aug 2015 20:48:17 -0500
Subject: [PATCH 132/146] cpu/amd/microcode: Introduce CBFS access spinlock to
 avoid IOMMU failure

---
 src/Kconfig                              |    4 ++++
 src/arch/x86/include/arch/smp/spinlock.h |    7 ++++++-
 src/cpu/amd/microcode/microcode.c        |   23 +++++++++++++++++++++++
 src/mainboard/asus/kgpe-d16/Kconfig      |    1 +
 src/mainboard/asus/kgpe-d16/romstage.c   |   15 ++++++++++++++-
 5 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index f1b7ebe..6b0df6a 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -455,6 +455,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 cf142a9..291c943 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 ce5b08f..fc6b0f2 100644
--- a/src/cpu/amd/microcode/microcode.c
+++ b/src/cpu/amd/microcode/microcode.c
@@ -24,6 +24,12 @@
 #include <cpu/amd/microcode.h>
 #include <cbfs.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)
 
@@ -106,12 +112,29 @@ void amd_update_microcode_from_cbfs(u32 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,
 					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 06116a2..5f421db 100644
--- a/src/mainboard/asus/kgpe-d16/Kconfig
+++ b/src/mainboard/asus/kgpe-d16/Kconfig
@@ -15,6 +15,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 3740bb0..6b5d801 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