]>
Commit | Line | Data |
---|---|---|
0d04f34a | 1 | /* |
f031f501 | 2 | * (C) Copyright 2012-2016 Stephen Warren |
0d04f34a | 3 | * |
a033171b | 4 | * SPDX-License-Identifier: GPL-2.0 |
0d04f34a SW |
5 | */ |
6 | ||
7 | #include <common.h> | |
757cd149 | 8 | #include <inttypes.h> |
ea697ae7 | 9 | #include <config.h> |
41e98e01 | 10 | #include <dm.h> |
1bcf7a30 | 11 | #include <efi_loader.h> |
5dfd162e | 12 | #include <fdt_support.h> |
033167c4 | 13 | #include <fdt_simplefb.h> |
ea697ae7 | 14 | #include <lcd.h> |
cf92e05c | 15 | #include <memalign.h> |
5dfd162e | 16 | #include <mmc.h> |
41e98e01 | 17 | #include <asm/gpio.h> |
3f397782 | 18 | #include <asm/arch/mbox.h> |
70997d88 | 19 | #include <asm/arch/msg.h> |
131a1e60 | 20 | #include <asm/arch/sdhci.h> |
0d04f34a | 21 | #include <asm/global_data.h> |
f031f501 | 22 | #include <dm/platform_data/serial_bcm283x_mu.h> |
d22a7657 SW |
23 | #ifdef CONFIG_ARM64 |
24 | #include <asm/armv8/mmu.h> | |
25 | #endif | |
45a6d231 | 26 | #include <watchdog.h> |
0d04f34a SW |
27 | |
28 | DECLARE_GLOBAL_DATA_PTR; | |
29 | ||
ade243a2 CS |
30 | /* From lowlevel_init.S */ |
31 | extern unsigned long fw_dtb_pointer; | |
32 | ||
3e16705d | 33 | /* TODO(sjg@chromium.org): Move these to the msg.c file */ |
3f397782 SW |
34 | struct msg_get_arm_mem { |
35 | struct bcm2835_mbox_hdr hdr; | |
36 | struct bcm2835_mbox_tag_get_arm_mem get_arm_mem; | |
37 | u32 end_tag; | |
38 | }; | |
39 | ||
6fe7845a SW |
40 | struct msg_get_board_rev { |
41 | struct bcm2835_mbox_hdr hdr; | |
42 | struct bcm2835_mbox_tag_get_board_rev get_board_rev; | |
43 | u32 end_tag; | |
44 | }; | |
45 | ||
757cd149 LR |
46 | struct msg_get_board_serial { |
47 | struct bcm2835_mbox_hdr hdr; | |
48 | struct bcm2835_mbox_tag_get_board_serial get_board_serial; | |
49 | u32 end_tag; | |
50 | }; | |
51 | ||
4f80a06d SW |
52 | struct msg_get_mac_address { |
53 | struct bcm2835_mbox_hdr hdr; | |
54 | struct bcm2835_mbox_tag_get_mac_address get_mac_address; | |
55 | u32 end_tag; | |
56 | }; | |
57 | ||
131a1e60 SW |
58 | struct msg_get_clock_rate { |
59 | struct bcm2835_mbox_hdr hdr; | |
60 | struct bcm2835_mbox_tag_get_clock_rate get_clock_rate; | |
61 | u32 end_tag; | |
62 | }; | |
63 | ||
5d3c4ba1 TT |
64 | #ifdef CONFIG_ARM64 |
65 | #define DTB_DIR "broadcom/" | |
66 | #else | |
67 | #define DTB_DIR "" | |
68 | #endif | |
69 | ||
dbe6f1eb SW |
70 | /* |
71 | * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/ | |
72 | * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733 | |
c4ea1edb | 73 | * http://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c;h=503151f61014418b9c42f4476a6086f75cd4e64b;hb=refs/heads/master#l922 |
dba060ce SW |
74 | * |
75 | * In http://lists.denx.de/pipermail/u-boot/2016-January/243752.html | |
76 | * ("[U-Boot] [PATCH] rpi: fix up Model B entries") Dom Cobley at the RPi | |
77 | * Foundation stated that the following source was accurate: | |
78 | * https://github.com/AndrewFromMelbourne/raspberry_pi_revision | |
dbe6f1eb | 79 | */ |
c4ea1edb | 80 | struct rpi_model { |
6fe7845a SW |
81 | const char *name; |
82 | const char *fdtfile; | |
3207d8fc | 83 | bool has_onboard_eth; |
c4ea1edb SW |
84 | }; |
85 | ||
86 | static const struct rpi_model rpi_model_unknown = { | |
87 | "Unknown model", | |
5d3c4ba1 | 88 | DTB_DIR "bcm283x-rpi-other.dtb", |
c4ea1edb SW |
89 | false, |
90 | }; | |
91 | ||
92 | static const struct rpi_model rpi_models_new_scheme[] = { | |
dbe6f1eb | 93 | [0x4] = { |
46414296 | 94 | "2 Model B", |
5d3c4ba1 | 95 | DTB_DIR "bcm2836-rpi-2-b.dtb", |
46414296 SW |
96 | true, |
97 | }, | |
7233fb31 SW |
98 | [0x8] = { |
99 | "3 Model B", | |
5d3c4ba1 | 100 | DTB_DIR "bcm2837-rpi-3-b.dtb", |
7233fb31 SW |
101 | true, |
102 | }, | |
af7c03ea SW |
103 | [0x9] = { |
104 | "Zero", | |
5d3c4ba1 | 105 | DTB_DIR "bcm2835-rpi-zero.dtb", |
af7c03ea SW |
106 | false, |
107 | }, | |
c4ea1edb SW |
108 | }; |
109 | ||
110 | static const struct rpi_model rpi_models_old_scheme[] = { | |
dbe6f1eb | 111 | [0x2] = { |
7443a9c4 | 112 | "Model B", |
5d3c4ba1 | 113 | DTB_DIR "bcm2835-rpi-b.dtb", |
3207d8fc | 114 | true, |
6fe7845a | 115 | }, |
dbe6f1eb | 116 | [0x3] = { |
7443a9c4 | 117 | "Model B", |
5d3c4ba1 | 118 | DTB_DIR "bcm2835-rpi-b.dtb", |
3207d8fc | 119 | true, |
6fe7845a | 120 | }, |
dbe6f1eb | 121 | [0x4] = { |
7443a9c4 | 122 | "Model B rev2", |
5d3c4ba1 | 123 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 124 | true, |
6fe7845a | 125 | }, |
dbe6f1eb | 126 | [0x5] = { |
7443a9c4 | 127 | "Model B rev2", |
5d3c4ba1 | 128 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 129 | true, |
6fe7845a | 130 | }, |
dbe6f1eb | 131 | [0x6] = { |
7443a9c4 | 132 | "Model B rev2", |
5d3c4ba1 | 133 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 134 | true, |
6fe7845a | 135 | }, |
dbe6f1eb | 136 | [0x7] = { |
6fe7845a | 137 | "Model A", |
5d3c4ba1 | 138 | DTB_DIR "bcm2835-rpi-a.dtb", |
3207d8fc | 139 | false, |
6fe7845a | 140 | }, |
dbe6f1eb | 141 | [0x8] = { |
6fe7845a | 142 | "Model A", |
5d3c4ba1 | 143 | DTB_DIR "bcm2835-rpi-a.dtb", |
3207d8fc | 144 | false, |
6fe7845a | 145 | }, |
dbe6f1eb | 146 | [0x9] = { |
6fe7845a | 147 | "Model A", |
5d3c4ba1 | 148 | DTB_DIR "bcm2835-rpi-a.dtb", |
3207d8fc | 149 | false, |
6fe7845a | 150 | }, |
dbe6f1eb | 151 | [0xd] = { |
6fe7845a | 152 | "Model B rev2", |
5d3c4ba1 | 153 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 154 | true, |
6fe7845a | 155 | }, |
dbe6f1eb | 156 | [0xe] = { |
6fe7845a | 157 | "Model B rev2", |
5d3c4ba1 | 158 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 159 | true, |
6fe7845a | 160 | }, |
dbe6f1eb | 161 | [0xf] = { |
6fe7845a | 162 | "Model B rev2", |
5d3c4ba1 | 163 | DTB_DIR "bcm2835-rpi-b-rev2.dtb", |
3207d8fc | 164 | true, |
6fe7845a | 165 | }, |
dbe6f1eb | 166 | [0x10] = { |
6fe7845a | 167 | "Model B+", |
5d3c4ba1 | 168 | DTB_DIR "bcm2835-rpi-b-plus.dtb", |
3207d8fc | 169 | true, |
6fe7845a | 170 | }, |
dbe6f1eb | 171 | [0x11] = { |
6fe7845a | 172 | "Compute Module", |
5d3c4ba1 | 173 | DTB_DIR "bcm2835-rpi-cm.dtb", |
3207d8fc | 174 | false, |
6fe7845a | 175 | }, |
dbe6f1eb | 176 | [0x12] = { |
47705eff | 177 | "Model A+", |
5d3c4ba1 | 178 | DTB_DIR "bcm2835-rpi-a-plus.dtb", |
47705eff SW |
179 | false, |
180 | }, | |
dbe6f1eb | 181 | [0x13] = { |
787affb4 | 182 | "Model B+", |
5d3c4ba1 | 183 | DTB_DIR "bcm2835-rpi-b-plus.dtb", |
787affb4 SW |
184 | true, |
185 | }, | |
dbe6f1eb | 186 | [0x14] = { |
787affb4 | 187 | "Compute Module", |
5d3c4ba1 | 188 | DTB_DIR "bcm2835-rpi-cm.dtb", |
787affb4 SW |
189 | false, |
190 | }, | |
dbe6f1eb | 191 | [0x15] = { |
79ad5cef | 192 | "Model A+", |
5d3c4ba1 | 193 | DTB_DIR "bcm2835-rpi-a-plus.dtb", |
79ad5cef LR |
194 | false, |
195 | }, | |
6fe7845a SW |
196 | }; |
197 | ||
c4ea1edb SW |
198 | static uint32_t revision; |
199 | static uint32_t rev_scheme; | |
200 | static uint32_t rev_type; | |
201 | static const struct rpi_model *model; | |
6fe7845a | 202 | |
d22a7657 SW |
203 | #ifdef CONFIG_ARM64 |
204 | static struct mm_region bcm2837_mem_map[] = { | |
205 | { | |
cd4b0c5f YS |
206 | .virt = 0x00000000UL, |
207 | .phys = 0x00000000UL, | |
d22a7657 SW |
208 | .size = 0x3f000000UL, |
209 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | |
210 | PTE_BLOCK_INNER_SHARE | |
211 | }, { | |
cd4b0c5f YS |
212 | .virt = 0x3f000000UL, |
213 | .phys = 0x3f000000UL, | |
d22a7657 SW |
214 | .size = 0x01000000UL, |
215 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | |
216 | PTE_BLOCK_NON_SHARE | | |
217 | PTE_BLOCK_PXN | PTE_BLOCK_UXN | |
218 | }, { | |
219 | /* List terminator */ | |
220 | 0, | |
221 | } | |
222 | }; | |
223 | ||
224 | struct mm_region *mem_map = bcm2837_mem_map; | |
225 | #endif | |
226 | ||
0d04f34a SW |
227 | int dram_init(void) |
228 | { | |
927753ae | 229 | ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1); |
3f397782 SW |
230 | int ret; |
231 | ||
232 | BCM2835_MBOX_INIT_HDR(msg); | |
233 | BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY); | |
234 | ||
235 | ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); | |
236 | if (ret) { | |
237 | printf("bcm2835: Could not query ARM memory size\n"); | |
238 | return -1; | |
239 | } | |
240 | ||
241 | gd->ram_size = msg->get_arm_mem.body.resp.mem_size; | |
0d04f34a SW |
242 | |
243 | return 0; | |
244 | } | |
245 | ||
6fe7845a SW |
246 | static void set_fdtfile(void) |
247 | { | |
248 | const char *fdtfile; | |
249 | ||
250 | if (getenv("fdtfile")) | |
251 | return; | |
252 | ||
c4ea1edb | 253 | fdtfile = model->fdtfile; |
382bee57 | 254 | env_set("fdtfile", fdtfile); |
6fe7845a SW |
255 | } |
256 | ||
ade243a2 CS |
257 | /* |
258 | * If the firmware provided a valid FDT at boot time, let's expose it in | |
259 | * ${fdt_addr} so it may be passed unmodified to the kernel. | |
260 | */ | |
261 | static void set_fdt_addr(void) | |
262 | { | |
263 | if (getenv("fdt_addr")) | |
264 | return; | |
265 | ||
266 | if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) | |
267 | return; | |
268 | ||
018f5303 | 269 | env_set_hex("fdt_addr", fw_dtb_pointer); |
ade243a2 CS |
270 | } |
271 | ||
272 | /* | |
273 | * Prevent relocation from stomping on a firmware provided FDT blob. | |
274 | */ | |
275 | unsigned long board_get_usable_ram_top(unsigned long total_size) | |
276 | { | |
277 | if ((gd->ram_top - fw_dtb_pointer) > SZ_64M) | |
278 | return gd->ram_top; | |
279 | return fw_dtb_pointer & ~0xffff; | |
280 | } | |
281 | ||
6fe7845a | 282 | static void set_usbethaddr(void) |
4f80a06d | 283 | { |
927753ae | 284 | ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1); |
4f80a06d SW |
285 | int ret; |
286 | ||
c4ea1edb | 287 | if (!model->has_onboard_eth) |
3207d8fc SW |
288 | return; |
289 | ||
4f80a06d | 290 | if (getenv("usbethaddr")) |
6fe7845a | 291 | return; |
4f80a06d SW |
292 | |
293 | BCM2835_MBOX_INIT_HDR(msg); | |
294 | BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS); | |
295 | ||
296 | ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); | |
297 | if (ret) { | |
298 | printf("bcm2835: Could not query MAC address\n"); | |
299 | /* Ignore error; not critical */ | |
6fe7845a | 300 | return; |
4f80a06d SW |
301 | } |
302 | ||
fd1e959e | 303 | eth_env_set_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac); |
4f80a06d | 304 | |
859f1437 | 305 | if (!getenv("ethaddr")) |
382bee57 | 306 | env_set("ethaddr", getenv("usbethaddr")); |
859f1437 | 307 | |
6fe7845a SW |
308 | return; |
309 | } | |
310 | ||
bff78567 GG |
311 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
312 | static void set_board_info(void) | |
313 | { | |
c4ea1edb SW |
314 | char s[11]; |
315 | ||
316 | snprintf(s, sizeof(s), "0x%X", revision); | |
382bee57 | 317 | env_set("board_revision", s); |
c4ea1edb | 318 | snprintf(s, sizeof(s), "%d", rev_scheme); |
382bee57 | 319 | env_set("board_rev_scheme", s); |
c4ea1edb SW |
320 | /* Can't rename this to board_rev_type since it's an ABI for scripts */ |
321 | snprintf(s, sizeof(s), "0x%X", rev_type); | |
382bee57 SG |
322 | env_set("board_rev", s); |
323 | env_set("board_name", model->name); | |
bff78567 GG |
324 | } |
325 | #endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */ | |
326 | ||
757cd149 LR |
327 | static void set_serial_number(void) |
328 | { | |
329 | ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_board_serial, msg, 1); | |
330 | int ret; | |
331 | char serial_string[17] = { 0 }; | |
332 | ||
333 | if (getenv("serial#")) | |
334 | return; | |
335 | ||
336 | BCM2835_MBOX_INIT_HDR(msg); | |
337 | BCM2835_MBOX_INIT_TAG_NO_REQ(&msg->get_board_serial, GET_BOARD_SERIAL); | |
338 | ||
339 | ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); | |
340 | if (ret) { | |
341 | printf("bcm2835: Could not query board serial\n"); | |
342 | /* Ignore error; not critical */ | |
343 | return; | |
344 | } | |
345 | ||
346 | snprintf(serial_string, sizeof(serial_string), "%016" PRIx64, | |
347 | msg->get_board_serial.body.resp.serial); | |
382bee57 | 348 | env_set("serial#", serial_string); |
757cd149 LR |
349 | } |
350 | ||
6fe7845a SW |
351 | int misc_init_r(void) |
352 | { | |
ade243a2 | 353 | set_fdt_addr(); |
6fe7845a SW |
354 | set_fdtfile(); |
355 | set_usbethaddr(); | |
bff78567 GG |
356 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
357 | set_board_info(); | |
358 | #endif | |
757cd149 LR |
359 | set_serial_number(); |
360 | ||
4f80a06d SW |
361 | return 0; |
362 | } | |
363 | ||
6fe7845a SW |
364 | static void get_board_rev(void) |
365 | { | |
927753ae | 366 | ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_board_rev, msg, 1); |
6fe7845a | 367 | int ret; |
c4ea1edb SW |
368 | const struct rpi_model *models; |
369 | uint32_t models_count; | |
6fe7845a SW |
370 | |
371 | BCM2835_MBOX_INIT_HDR(msg); | |
372 | BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV); | |
373 | ||
374 | ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); | |
375 | if (ret) { | |
376 | printf("bcm2835: Could not query board revision\n"); | |
377 | /* Ignore error; not critical */ | |
378 | return; | |
379 | } | |
380 | ||
46414296 SW |
381 | /* |
382 | * For details of old-vs-new scheme, see: | |
383 | * https://github.com/pimoroni/RPi.version/blob/master/RPi/version.py | |
384 | * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=99293&p=690282 | |
385 | * (a few posts down) | |
95b4f112 SW |
386 | * |
387 | * For the RPi 1, bit 24 is the "warranty bit", so we mask off just the | |
388 | * lower byte to use as the board rev: | |
389 | * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250 | |
390 | * http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594 | |
46414296 | 391 | */ |
c4ea1edb SW |
392 | revision = msg->get_board_rev.body.resp.rev; |
393 | if (revision & 0x800000) { | |
394 | rev_scheme = 1; | |
395 | rev_type = (revision >> 4) & 0xff; | |
396 | models = rpi_models_new_scheme; | |
397 | models_count = ARRAY_SIZE(rpi_models_new_scheme); | |
398 | } else { | |
399 | rev_scheme = 0; | |
400 | rev_type = revision & 0xff; | |
401 | models = rpi_models_old_scheme; | |
402 | models_count = ARRAY_SIZE(rpi_models_old_scheme); | |
47705eff | 403 | } |
c4ea1edb SW |
404 | if (rev_type >= models_count) { |
405 | printf("RPI: Board rev 0x%x outside known range\n", rev_type); | |
406 | model = &rpi_model_unknown; | |
407 | } else if (!models[rev_type].name) { | |
408 | printf("RPI: Board rev 0x%x unknown\n", rev_type); | |
409 | model = &rpi_model_unknown; | |
410 | } else { | |
411 | model = &models[rev_type]; | |
47705eff | 412 | } |
914627fe | 413 | |
c4ea1edb | 414 | printf("RPI %s (0x%x)\n", model->name, revision); |
6fe7845a SW |
415 | } |
416 | ||
601147b0 AG |
417 | #ifndef CONFIG_PL01X_SERIAL |
418 | static bool rpi_is_serial_active(void) | |
419 | { | |
420 | int serial_gpio = 15; | |
421 | struct udevice *dev; | |
422 | ||
423 | /* | |
424 | * The RPi3 disables the mini uart by default. The easiest way to find | |
425 | * out whether it is available is to check if the RX pin is muxed. | |
426 | */ | |
427 | ||
428 | if (uclass_first_device(UCLASS_GPIO, &dev) || !dev) | |
429 | return true; | |
430 | ||
431 | if (bcm2835_gpio_get_func_id(dev, serial_gpio) != BCM2835_GPIO_ALT5) | |
432 | return false; | |
433 | ||
434 | return true; | |
435 | } | |
d8396a32 FV |
436 | |
437 | /* Disable mini-UART I/O if it's not pinmuxed to our pins. | |
438 | * The firmware only enables it if explicitly done in config.txt: enable_uart=1 | |
439 | */ | |
440 | static void rpi_disable_inactive_uart(void) | |
441 | { | |
442 | struct udevice *dev; | |
443 | struct bcm283x_mu_serial_platdata *plat; | |
444 | ||
445 | if (uclass_get_device_by_driver(UCLASS_SERIAL, | |
446 | DM_GET_DRIVER(serial_bcm283x_mu), | |
447 | &dev) || !dev) | |
448 | return; | |
449 | ||
450 | if (!rpi_is_serial_active()) { | |
451 | plat = dev_get_platdata(dev); | |
452 | plat->disabled = true; | |
453 | } | |
454 | } | |
601147b0 AG |
455 | #endif |
456 | ||
d8396a32 | 457 | int board_init(void) |
601147b0 | 458 | { |
45a6d231 PP |
459 | #ifdef CONFIG_HW_WATCHDOG |
460 | hw_watchdog_init(); | |
461 | #endif | |
601147b0 | 462 | #ifndef CONFIG_PL01X_SERIAL |
d8396a32 | 463 | rpi_disable_inactive_uart(); |
601147b0 AG |
464 | #endif |
465 | ||
d8396a32 FV |
466 | get_board_rev(); |
467 | ||
468 | gd->bd->bi_boot_params = 0x100; | |
469 | ||
70997d88 | 470 | return bcm2835_power_on_module(BCM2835_MBOX_POWER_DEVID_USB_HCD); |
601147b0 AG |
471 | } |
472 | ||
82f766d1 AD |
473 | /* |
474 | * If the firmware passed a device tree use it for U-Boot. | |
475 | */ | |
476 | void *board_fdt_blob_setup(void) | |
477 | { | |
478 | if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) | |
479 | return NULL; | |
480 | return (void *)fw_dtb_pointer; | |
481 | } | |
482 | ||
e895a4b0 | 483 | int ft_board_setup(void *blob, bd_t *bd) |
ea697ae7 SW |
484 | { |
485 | /* | |
486 | * For now, we simply always add the simplefb DT node. Later, we | |
487 | * should be more intelligent, and e.g. only do this if no enabled DT | |
488 | * node exists for the "real" graphics driver. | |
489 | */ | |
490 | lcd_dt_simplefb_add_node(blob); | |
e895a4b0 | 491 | |
1bcf7a30 AG |
492 | #ifdef CONFIG_EFI_LOADER |
493 | /* Reserve the spin table */ | |
494 | efi_add_memory_map(0, 1, EFI_RESERVED_MEMORY_TYPE, 0); | |
495 | #endif | |
496 | ||
e895a4b0 | 497 | return 0; |
ea697ae7 | 498 | } |