summaryrefslogtreecommitdiff
path: root/resources/coreboot/haswell/patches/0004-haswell-lynxpoint-Add-native-early-ME-init.patch
blob: 28dbc02a3568b6d352cab82711f4a6e111851bfd (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
From 98142e01fc8ebb3b762974e9e4de75e7f5c073b4 Mon Sep 17 00:00:00 2001
From: Angel Pons <th3fanbus@gmail.com>
Date: Fri, 6 May 2022 22:18:21 +0200
Subject: [PATCH 04/26] haswell/lynxpoint: Add native early ME init

Implement native early ME init for Lynx Point. This is only needed when
MRC.bin is not used.

Change-Id: If416e2078f139f26b4742c564b70e018725bf003
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
---
 .../haswell/native_raminit/raminit_native.c   | 17 ++++++++++-
 src/southbridge/intel/lynxpoint/early_me.c    | 30 ++++++++++++++++++-
 src/southbridge/intel/lynxpoint/me.h          |  7 +++--
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c
index 0938e026e3..6a002548c1 100644
--- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c
+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c
@@ -1,18 +1,24 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
 #include <console/console.h>
+#include <delay.h>
 #include <northbridge/intel/haswell/haswell.h>
 #include <northbridge/intel/haswell/raminit.h>
+#include <southbridge/intel/lynxpoint/me.h>
 #include <types.h>
 
 static bool early_init_native(int s3resume)
 {
 	printk(BIOS_DEBUG, "Starting native platform initialisation\n");
 
+	intel_early_me_init();
+	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/
+	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check();
+
 	if (!CONFIG(INTEL_LYNXPOINT_LP))
 		dmi_early_init();
 
-	return false;
+	return cpu_replaced;
 }
 
 void perform_raminit(const int s3resume)
@@ -25,6 +31,15 @@ void perform_raminit(const int s3resume)
 
 	(void)cpu_replaced;
 
+	/** TODO: Move after raminit */
+	if (intel_early_me_uma_size() > 0) {
+		/** TODO: Update status once raminit is implemented **/
+		uint8_t me_status = ME_INIT_STATUS_ERROR;
+		intel_early_me_init_done(me_status);
+	}
+
+	intel_early_me_status();
+
 	/** TODO: Implement the required magic **/
 	die("NATIVE RAMINIT: More Magic (tm) required.\n");
 }
diff --git a/src/southbridge/intel/lynxpoint/early_me.c b/src/southbridge/intel/lynxpoint/early_me.c
index 947c570e16..07013c5539 100644
--- a/src/southbridge/intel/lynxpoint/early_me.c
+++ b/src/southbridge/intel/lynxpoint/early_me.c
@@ -1,11 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
 #include <arch/io.h>
+#include <cf9_reset.h>
 #include <device/pci_ops.h>
 #include <console/console.h>
 #include <delay.h>
 #include <halt.h>
-
+#include <timer.h>
 #include "me.h"
 #include "pch.h"
 
@@ -60,6 +61,33 @@ int intel_early_me_init(void)
 	return 0;
 }
 
+bool intel_early_me_cpu_replacement_check(void)
+{
+	printk(BIOS_DEBUG, "ME: Checking whether CPU was replaced... ");
+
+	struct stopwatch timer;
+	stopwatch_init_msecs_expire(&timer, 50);
+
+	union me_hfs2 hfs2;
+	do {
+		hfs2.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS2);
+		if (stopwatch_expired(&timer)) {
+			/* Assume CPU was replaced just in case */
+			printk(BIOS_DEBUG, "timed out, assuming CPU was replaced\n");
+			return true;
+		}
+		udelay(ME_DELAY);
+	} while (!hfs2.cpu_replaced_valid);
+
+	if (hfs2.warm_reset_request) {
+		printk(BIOS_DEBUG, "warm reset needed for dynamic fusing\n");
+		system_reset();
+	}
+
+	printk(BIOS_DEBUG, "%sreplaced\n", hfs2.cpu_replaced_sts ? "" : "not ");
+	return hfs2.cpu_replaced_sts;
+}
+
 int intel_early_me_uma_size(void)
 {
 	union me_uma uma = { .raw = pci_read_config32(PCH_ME_DEV, PCI_ME_UMA) };
diff --git a/src/southbridge/intel/lynxpoint/me.h b/src/southbridge/intel/lynxpoint/me.h
index fe8b0260c4..6990322651 100644
--- a/src/southbridge/intel/lynxpoint/me.h
+++ b/src/southbridge/intel/lynxpoint/me.h
@@ -177,14 +177,16 @@ union me_did {
 union me_hfs2 {
 	struct __packed {
 		u32 bist_in_progress: 1;
-		u32 reserved1: 2;
+		u32 icc_prog_sts: 2;
 		u32 invoke_mebx: 1;
 		u32 cpu_replaced_sts: 1;
 		u32 mbp_rdy: 1;
 		u32 mfs_failure: 1;
 		u32 warm_reset_request: 1;
 		u32 cpu_replaced_valid: 1;
-		u32 reserved2: 4;
+		u32 reserved: 2;
+		u32 fw_upd_ipu: 1;
+		u32 reserved2: 1;
 		u32 mbp_cleared: 1;
 		u32 reserved3: 2;
 		u32 current_state: 8;
@@ -338,6 +340,7 @@ void intel_me_status(union me_hfs hfs, union me_hfs2 hfs2);
 
 void intel_early_me_status(void);
 int intel_early_me_init(void);
+bool intel_early_me_cpu_replacement_check(void);
 int intel_early_me_uma_size(void);
 int intel_early_me_init_done(u8 status);
 
-- 
2.39.2