summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/kgpe-d16/0001-util-cbmem-Fix-failure-with-certain-cbmem-base-align.patch
blob: 84c51ba13824e56f2e3e15c7c8044b3ed2ff492f (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
194
195
196
197
198
199
200
201
202
203
204
205
From 4e0a69562a189e9abe06979a993f50e3f0b2069b Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Sat, 5 Sep 2015 18:07:17 -0500
Subject: [PATCH 001/146] util/cbmem: Fix failure with certain cbmem base
 alignments

---
 util/cbmem/cbmem.c |   61 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 74cb52d..69ffbaf 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright 2012 Google Inc.
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -103,8 +104,7 @@ static void unmap_memory(void)
 	if (size_to_mib(mapped_size) == 0) {
 		debug("Unmapping %zuMB of virtual memory at %p.\n",
 		      size_to_mib(mapped_size), mapped_virtual);
-	}
-	else {
+	} else {
 		debug("Unmapping %zuMB of virtual memory at %p.\n",
 		      size_to_mib(mapped_size), mapped_virtual);
 	}
@@ -113,7 +113,7 @@ static void unmap_memory(void)
 	mapped_size = 0;
 }
 
-static void *map_memory_size(u64 physical, size_t size)
+static void *map_memory_size(u64 physical, size_t size, uint8_t abort_on_failure)
 {
 	void *v;
 	off_t p;
@@ -131,8 +131,7 @@ static void *map_memory_size(u64 physical, size_t size)
 	if (size_to_mib(size) == 0) {
 		debug("Mapping %zuB of physical memory at 0x%jx (requested 0x%jx).\n",
 		      size, (intmax_t)p, (intmax_t)physical);
-	}
-	else {
+	} else {
 		debug("Mapping %zuMB of physical memory at 0x%jx (requested 0x%jx).\n",
 		      size_to_mib(size), (intmax_t)p, (intmax_t)physical);
 	}
@@ -153,9 +152,13 @@ static void *map_memory_size(u64 physical, size_t size)
 	}
 
 	if (v == MAP_FAILED) {
-		fprintf(stderr, "Failed to mmap /dev/mem: %s\n",
-			strerror(errno));
-		exit(1);
+		if (abort_on_failure) {
+			fprintf(stderr, "Failed to mmap /dev/mem: %s\n",
+				strerror(errno));
+			exit(1);
+		} else {
+			return 0;
+		}
 	}
 
 	/* Remember what we actually mapped ... */
@@ -173,7 +176,7 @@ static void *map_memory_size(u64 physical, size_t size)
 
 static void *map_memory(u64 physical)
 {
-	return map_memory_size(physical, MAP_BYTES);
+	return map_memory_size(physical, MAP_BYTES, 1);
 }
 
 /*
@@ -210,14 +213,16 @@ static struct lb_cbmem_ref parse_cbmem_ref(struct lb_cbmem_ref *cbmem_ref)
 	return ret;
 }
 
-static int parse_cbtable(u64 address, size_t table_size)
+static int parse_cbtable(u64 address, size_t table_size, uint8_t abort_on_failure)
 {
-	int i, found = 0;
+	int i, found, ret = 0;
 	void *buf;
 
 	debug("Looking for coreboot table at %" PRIx64 " %zd bytes.\n",
 		address, table_size);
-	buf = map_memory_size(address, table_size);
+	buf = map_memory_size(address, table_size, abort_on_failure);
+	if (!buf)
+		return -2;
 
 	/* look at every 16 bytes within 4K of the base */
 
@@ -283,7 +288,17 @@ static int parse_cbtable(u64 address, size_t table_size)
 					*(struct lb_forward *) lbr_p;
 				debug("    Found forwarding entry.\n");
 				unmap_memory();
-				return parse_cbtable(lbf_p.forward, table_size);
+				ret = parse_cbtable(lbf_p.forward, table_size, 0);
+				if (ret == -2) {
+					/* try again with a smaller memory mapping request */
+					ret = parse_cbtable(lbf_p.forward, table_size / 2, 1);
+					if (ret == -2)
+						exit(1);
+					else
+						return ret;
+				} else {
+					return ret;
+				}
 			}
 			default:
 				break;
@@ -544,7 +559,7 @@ static void dump_timestamps(int mach_readable)
 	}
 
 	size = sizeof(*tst_p);
-	tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size);
+	tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size, 1);
 
 	timestamp_set_tick_freq(tst_p->tick_freq_mhz);
 
@@ -553,7 +568,7 @@ static void dump_timestamps(int mach_readable)
 	size += tst_p->num_entries * sizeof(tst_p->entries[0]);
 
 	unmap_memory();
-	tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size);
+	tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size, 1);
 
 	/* Report the base time within the table. */
 	prev_stamp = 0;
@@ -604,7 +619,7 @@ static void dump_console(void)
 	}
 
 	console_p = map_memory_size((unsigned long)console.cbmem_addr,
-					2 * sizeof(uint32_t));
+					2 * sizeof(uint32_t), 1);
 	/* The in-memory format of the console area is:
 	 *  u32  size
 	 *  u32  cursor
@@ -626,7 +641,7 @@ static void dump_console(void)
 	}
 
 	console_p = map_memory_size((unsigned long)console.cbmem_addr,
-	                            size + sizeof(size) + sizeof(cursor));
+	                            size + sizeof(size) + sizeof(cursor), 1);
 	memcpy(console_c, console_p + 8, size);
 	console_c[size] = 0;
 	console_c[cursor] = 0;
@@ -647,7 +662,7 @@ static void hexdump(unsigned long memory, int length)
 	uint8_t *m;
 	int all_zero = 0;
 
-	m = map_memory_size((intptr_t)memory, length);
+	m = map_memory_size((intptr_t)memory, length, 1);
 
 	if (length > MAP_BYTES) {
 		printf("Truncating hex dump from %d to %d bytes\n\n",
@@ -803,7 +818,7 @@ static void dump_cbmem_toc(void)
 
 	start = unpack_lb64(cbmem.start);
 
-	cbmem_area = map_memory_size(start, unpack_lb64(cbmem.size));
+	cbmem_area = map_memory_size(start, unpack_lb64(cbmem.size), 1);
 	entries = (struct cbmem_entry *)cbmem_area;
 
 	if (entries[0].magic == CBMEM_MAGIC) {
@@ -814,12 +829,12 @@ static void dump_cbmem_toc(void)
 		rootptr -= sizeof(struct cbmem_root_pointer);
 		unmap_memory();
 		struct cbmem_root_pointer *r =
-			map_memory_size(rootptr, sizeof(*r));
+			map_memory_size(rootptr, sizeof(*r), 1);
 		if (r->magic == CBMEM_POINTER_MAGIC) {
 			struct cbmem_root *root;
 			uint64_t rootaddr = rootptr + r->root_offset;
 			unmap_memory();
-			root = map_memory_size(rootaddr, ROOT_MIN_SIZE);
+			root = map_memory_size(rootaddr, ROOT_MIN_SIZE, 1);
 			dump_dynamic_cbmem_toc(root);
 		} else
 			fprintf(stderr, "No valid coreboot CBMEM root pointer found.\n");
@@ -1205,14 +1220,14 @@ int main(int argc, char** argv)
 		dtbuffer++;
 	}
 
-	parse_cbtable(baseaddr, cb_table_size);
+	parse_cbtable(baseaddr, cb_table_size, 1);
 #else
 	int j;
 	static const int possible_base_addresses[] = { 0, 0xf0000 };
 
 	/* Find and parse coreboot table */
 	for (j = 0; j < ARRAY_SIZE(possible_base_addresses); j++) {
-		if (parse_cbtable(possible_base_addresses[j], MAP_BYTES))
+		if (parse_cbtable(possible_base_addresses[j], MAP_BYTES, 1))
 			break;
 	}
 #endif
-- 
1.7.9.5