eboot.c 27.3 KB
Newer Older
M
Matt Fleming 已提交
1 2 3 4 5 6 7 8 9 10
/* -----------------------------------------------------------------------
 *
 *   Copyright 2011 Intel Corporation; author Matt Fleming
 *
 *   This file is part of the Linux kernel, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

#include <linux/efi.h>
11
#include <linux/pci.h>
12

M
Matt Fleming 已提交
13
#include <asm/efi.h>
14
#include <asm/e820/types.h>
M
Matt Fleming 已提交
15 16 17
#include <asm/setup.h>
#include <asm/desc.h>

18
#include "../string.h"
M
Matt Fleming 已提交
19 20 21 22
#include "eboot.h"

static efi_system_table_t *sys_table;

23 24
static struct efi_config *efi_early;

A
Ard Biesheuvel 已提交
25 26 27 28
__pure const struct efi_config *__efi_early(void)
{
	return efi_early;
}
29

30 31 32 33 34 35 36
#define BOOT_SERVICES(bits)						\
static void setup_boot_services##bits(struct efi_config *c)		\
{									\
	efi_system_table_##bits##_t *table;				\
									\
	table = (typeof(table))sys_table;				\
									\
37
	c->runtime_services = table->runtime;				\
38
	c->boot_services = table->boottime;				\
39 40 41 42
	c->text_output = table->con_out;				\
}
BOOT_SERVICES(32);
BOOT_SERVICES(64);
M
Matt Fleming 已提交
43

44 45 46 47 48 49 50 51 52 53
static inline efi_status_t __open_volume32(void *__image, void **__fh)
{
	efi_file_io_interface_t *io;
	efi_loaded_image_32_t *image = __image;
	efi_file_handle_32_t *fh;
	efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
	efi_status_t status;
	void *handle = (void *)(unsigned long)image->device_handle;
	unsigned long func;

54 55
	status = efi_call_early(handle_protocol, handle,
				&fs_proto, (void **)&io);
56 57 58 59 60 61 62 63 64
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to handle fs_proto\n");
		return status;
	}

	func = (unsigned long)io->open_volume;
	status = efi_early->call(func, io, &fh);
	if (status != EFI_SUCCESS)
		efi_printk(sys_table, "Failed to open volume\n");
M
Matt Fleming 已提交
65

66 67
	*__fh = fh;
	return status;
68 69
}

70
static inline efi_status_t __open_volume64(void *__image, void **__fh)
71 72
{
	efi_file_io_interface_t *io;
73 74
	efi_loaded_image_64_t *image = __image;
	efi_file_handle_64_t *fh;
75 76 77
	efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
	efi_status_t status;
	void *handle = (void *)(unsigned long)image->device_handle;
78
	unsigned long func;
79

80 81
	status = efi_call_early(handle_protocol, handle,
				&fs_proto, (void **)&io);
82 83 84 85
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to handle fs_proto\n");
		return status;
	}
M
Matt Fleming 已提交
86

87 88 89 90 91 92 93 94 95
	func = (unsigned long)io->open_volume;
	status = efi_early->call(func, io, &fh);
	if (status != EFI_SUCCESS)
		efi_printk(sys_table, "Failed to open volume\n");

	*__fh = fh;
	return status;
}

96
efi_status_t
97 98 99 100 101 102 103 104
efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
{
	if (efi_early->is64)
		return __open_volume64(__image, __fh);

	return __open_volume32(__image, __fh);
}

105
void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
106
{
107 108
	efi_call_proto(efi_simple_text_output_protocol, output_string,
		       efi_early->text_output, str);
109 110
}

111 112
static efi_status_t
__setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
113
{
114
	struct pci_setup_rom *rom = NULL;
115
	efi_status_t status;
116 117
	unsigned long size;
	uint64_t attributes;
118

119 120 121 122 123
	status = efi_early->call(pci->attributes, pci,
				 EfiPciIoAttributeOperationGet, 0, 0,
				 &attributes);
	if (status != EFI_SUCCESS)
		return status;
124

125 126
	if (!pci->romimage || !pci->romsize)
		return EFI_INVALID_PARAMETER;
127

128
	size = pci->romsize + sizeof(*rom);
129

130
	status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
131 132
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to alloc mem for rom\n");
133
		return status;
134
	}
135

136 137 138 139 140 141 142 143 144 145
	memset(rom, 0, sizeof(*rom));

	rom->data.type = SETUP_PCI;
	rom->data.len = size - sizeof(struct setup_data);
	rom->data.next = 0;
	rom->pcilen = pci->romsize;
	*__rom = rom;

	status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
				 PCI_VENDOR_ID, 1, &(rom->vendor));
146

147 148
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to read rom->vendor\n");
149
		goto free_struct;
150
	}
151 152 153 154

	status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
				 PCI_DEVICE_ID, 1, &(rom->devid));

155 156
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to read rom->devid\n");
157
		goto free_struct;
158
	}
159 160 161 162 163 164 165 166 167 168 169

	status = efi_early->call(pci->get_location, pci, &(rom->segment),
				 &(rom->bus), &(rom->device), &(rom->function));

	if (status != EFI_SUCCESS)
		goto free_struct;

	memcpy(rom->romdata, pci->romimage, pci->romsize);
	return status;

free_struct:
170
	efi_call_early(free_pool, rom);
171 172 173
	return status;
}

174
static void
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
setup_efi_pci32(struct boot_params *params, void **pci_handle,
		unsigned long size)
{
	efi_pci_io_protocol_32 *pci = NULL;
	efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
	u32 *handles = (u32 *)(unsigned long)pci_handle;
	efi_status_t status;
	unsigned long nr_pci;
	struct setup_data *data;
	int i;

	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;

	while (data && data->next)
		data = (struct setup_data *)(unsigned long)data->next;
190

191
	nr_pci = size / sizeof(u32);
192
	for (i = 0; i < nr_pci; i++) {
193 194
		struct pci_setup_rom *rom = NULL;
		u32 h = handles[i];
195

196 197
		status = efi_call_early(handle_protocol, h,
					&pci_proto, (void **)&pci);
198 199 200 201 202 203 204

		if (status != EFI_SUCCESS)
			continue;

		if (!pci)
			continue;

205
		status = __setup_efi_pci32(pci, &rom);
206 207 208
		if (status != EFI_SUCCESS)
			continue;

209 210 211 212 213 214
		if (data)
			data->next = (unsigned long)rom;
		else
			params->hdr.setup_data = (unsigned long)rom;

		data = (struct setup_data *)rom;
215

216 217
	}
}
218

219 220 221 222 223 224 225
static efi_status_t
__setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
{
	struct pci_setup_rom *rom;
	efi_status_t status;
	unsigned long size;
	uint64_t attributes;
226

227 228 229 230 231
	status = efi_early->call(pci->attributes, pci,
				 EfiPciIoAttributeOperationGet, 0,
				 &attributes);
	if (status != EFI_SUCCESS)
		return status;
232

233 234
	if (!pci->romimage || !pci->romsize)
		return EFI_INVALID_PARAMETER;
235

236
	size = pci->romsize + sizeof(*rom);
237

238
	status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom);
239 240
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to alloc mem for rom\n");
241
		return status;
242
	}
243 244 245 246 247 248 249 250 251 252

	rom->data.type = SETUP_PCI;
	rom->data.len = size - sizeof(struct setup_data);
	rom->data.next = 0;
	rom->pcilen = pci->romsize;
	*__rom = rom;

	status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
				 PCI_VENDOR_ID, 1, &(rom->vendor));

253 254
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to read rom->vendor\n");
255
		goto free_struct;
256
	}
257 258 259 260

	status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16,
				 PCI_DEVICE_ID, 1, &(rom->devid));

261 262
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "Failed to read rom->devid\n");
263
		goto free_struct;
264
	}
265 266 267 268 269 270 271 272 273 274 275

	status = efi_early->call(pci->get_location, pci, &(rom->segment),
				 &(rom->bus), &(rom->device), &(rom->function));

	if (status != EFI_SUCCESS)
		goto free_struct;

	memcpy(rom->romdata, pci->romimage, pci->romsize);
	return status;

free_struct:
276
	efi_call_early(free_pool, rom);
277 278 279 280
	return status;

}

281
static void
282 283 284 285 286 287 288 289 290 291
setup_efi_pci64(struct boot_params *params, void **pci_handle,
		unsigned long size)
{
	efi_pci_io_protocol_64 *pci = NULL;
	efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
	u64 *handles = (u64 *)(unsigned long)pci_handle;
	efi_status_t status;
	unsigned long nr_pci;
	struct setup_data *data;
	int i;
292

293 294 295 296 297 298 299 300 301 302
	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;

	while (data && data->next)
		data = (struct setup_data *)(unsigned long)data->next;

	nr_pci = size / sizeof(u64);
	for (i = 0; i < nr_pci; i++) {
		struct pci_setup_rom *rom = NULL;
		u64 h = handles[i];

303 304
		status = efi_call_early(handle_protocol, h,
					&pci_proto, (void **)&pci);
305 306

		if (status != EFI_SUCCESS)
307 308 309 310
			continue;

		if (!pci)
			continue;
311

312 313 314
		status = __setup_efi_pci64(pci, &rom);
		if (status != EFI_SUCCESS)
			continue;
315 316

		if (data)
317
			data->next = (unsigned long)rom;
318
		else
319
			params->hdr.setup_data = (unsigned long)rom;
320 321 322 323 324 325

		data = (struct setup_data *)rom;

	}
}

326 327 328 329 330 331 332 333 334 335
/*
 * There's no way to return an informative status from this function,
 * because any analysis (and printing of error messages) needs to be
 * done directly at the EFI function call-site.
 *
 * For example, EFI_INVALID_PARAMETER could indicate a bug or maybe we
 * just didn't find any PCI devices, but there's no way to tell outside
 * the context of the call.
 */
static void setup_efi_pci(struct boot_params *params)
M
Matt Fleming 已提交
336 337
{
	efi_status_t status;
338 339 340
	void **pci_handle = NULL;
	efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
	unsigned long size = 0;
M
Matt Fleming 已提交
341

342 343 344
	status = efi_call_early(locate_handle,
				EFI_LOCATE_BY_PROTOCOL,
				&pci_proto, NULL, &size, pci_handle);
M
Matt Fleming 已提交
345

346
	if (status == EFI_BUFFER_TOO_SMALL) {
347 348 349
		status = efi_call_early(allocate_pool,
					EFI_LOADER_DATA,
					size, (void **)&pci_handle);
M
Matt Fleming 已提交
350

351 352
		if (status != EFI_SUCCESS) {
			efi_printk(sys_table, "Failed to alloc mem for pci_handle\n");
353
			return;
354
		}
M
Matt Fleming 已提交
355

356 357 358
		status = efi_call_early(locate_handle,
					EFI_LOCATE_BY_PROTOCOL, &pci_proto,
					NULL, &size, pci_handle);
M
Matt Fleming 已提交
359 360
	}

361
	if (status != EFI_SUCCESS)
M
Matt Fleming 已提交
362 363
		goto free_handle;

364
	if (efi_early->is64)
365
		setup_efi_pci64(params, pci_handle, size);
366
	else
367
		setup_efi_pci32(params, pci_handle, size);
M
Matt Fleming 已提交
368

369
free_handle:
370
	efi_call_early(free_pool, pci_handle);
371
}
M
Matt Fleming 已提交
372

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
static void retrieve_apple_device_properties(struct boot_params *boot_params)
{
	efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
	struct setup_data *data, *new;
	efi_status_t status;
	u32 size = 0;
	void *p;

	status = efi_call_early(locate_protocol, &guid, NULL, &p);
	if (status != EFI_SUCCESS)
		return;

	if (efi_table_attr(apple_properties_protocol, version, p) != 0x10000) {
		efi_printk(sys_table, "Unsupported properties proto version\n");
		return;
	}

	efi_call_proto(apple_properties_protocol, get_all, p, NULL, &size);
	if (!size)
		return;

	do {
		status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
					size + sizeof(struct setup_data), &new);
		if (status != EFI_SUCCESS) {
			efi_printk(sys_table,
					"Failed to alloc mem for properties\n");
			return;
		}

		status = efi_call_proto(apple_properties_protocol, get_all, p,
					new->data, &size);

		if (status == EFI_BUFFER_TOO_SMALL)
			efi_call_early(free_pool, new);
	} while (status == EFI_BUFFER_TOO_SMALL);

	new->type = SETUP_APPLE_PROPERTIES;
	new->len  = size;
	new->next = 0;

	data = (struct setup_data *)(unsigned long)boot_params->hdr.setup_data;
	if (!data)
		boot_params->hdr.setup_data = (unsigned long)new;
	else {
		while (data->next)
			data = (struct setup_data *)(unsigned long)data->next;
		data->next = (unsigned long)new;
	}
}

static void setup_quirks(struct boot_params *boot_params)
{
	efi_char16_t const apple[] = { 'A', 'p', 'p', 'l', 'e', 0 };
	efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
		efi_table_attr(efi_system_table, fw_vendor, sys_table);

	if (!memcmp(fw_vendor, apple, sizeof(apple))) {
		if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
			retrieve_apple_device_properties(boot_params);
	}
}

436 437 438 439 440 441 442
static efi_status_t
setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
{
	struct efi_uga_draw_protocol *uga = NULL, *first_uga;
	efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
	unsigned long nr_ugas;
	u32 *handles = (u32 *)uga_handle;;
443
	efi_status_t status = EFI_INVALID_PARAMETER;
444 445
	int i;

M
Matt Fleming 已提交
446
	first_uga = NULL;
447 448 449 450 451 452 453
	nr_ugas = size / sizeof(u32);
	for (i = 0; i < nr_ugas; i++) {
		efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
		u32 w, h, depth, refresh;
		void *pciio;
		u32 handle = handles[i];

454 455
		status = efi_call_early(handle_protocol, handle,
					&uga_proto, (void **)&uga);
456 457 458
		if (status != EFI_SUCCESS)
			continue;

459
		efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

		status = efi_early->call((unsigned long)uga->get_mode, uga,
					 &w, &h, &depth, &refresh);
		if (status == EFI_SUCCESS && (!first_uga || pciio)) {
			*width = w;
			*height = h;

			/*
			 * Once we've found a UGA supporting PCIIO,
			 * don't bother looking any further.
			 */
			if (pciio)
				break;

			first_uga = uga;
		}
	}

	return status;
}
M
Matt Fleming 已提交
480

481 482 483 484 485 486 487
static efi_status_t
setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
{
	struct efi_uga_draw_protocol *uga = NULL, *first_uga;
	efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
	unsigned long nr_ugas;
	u64 *handles = (u64 *)uga_handle;;
488
	efi_status_t status = EFI_INVALID_PARAMETER;
489 490 491 492
	int i;

	first_uga = NULL;
	nr_ugas = size / sizeof(u64);
M
Matt Fleming 已提交
493 494 495 496
	for (i = 0; i < nr_ugas; i++) {
		efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
		u32 w, h, depth, refresh;
		void *pciio;
497
		u64 handle = handles[i];
M
Matt Fleming 已提交
498

499 500
		status = efi_call_early(handle_protocol, handle,
					&uga_proto, (void **)&uga);
M
Matt Fleming 已提交
501 502 503
		if (status != EFI_SUCCESS)
			continue;

504
		efi_call_early(handle_protocol, handle, &pciio_proto, &pciio);
M
Matt Fleming 已提交
505

506 507
		status = efi_early->call((unsigned long)uga->get_mode, uga,
					 &w, &h, &depth, &refresh);
M
Matt Fleming 已提交
508
		if (status == EFI_SUCCESS && (!first_uga || pciio)) {
509 510
			*width = w;
			*height = h;
M
Matt Fleming 已提交
511 512 513 514 515 516 517 518 519 520 521 522

			/*
			 * Once we've found a UGA supporting PCIIO,
			 * don't bother looking any further.
			 */
			if (pciio)
				break;

			first_uga = uga;
		}
	}

523 524 525 526 527 528 529 530 531 532 533 534 535
	return status;
}

/*
 * See if we have Universal Graphics Adapter (UGA) protocol
 */
static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
			      unsigned long size)
{
	efi_status_t status;
	u32 width, height;
	void **uga_handle = NULL;

536 537
	status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
				size, (void **)&uga_handle);
538 539 540
	if (status != EFI_SUCCESS)
		return status;

541 542 543
	status = efi_call_early(locate_handle,
				EFI_LOCATE_BY_PROTOCOL,
				uga_proto, NULL, &size, uga_handle);
544 545 546 547 548 549 550 551 552 553 554 555
	if (status != EFI_SUCCESS)
		goto free_handle;

	height = 0;
	width = 0;

	if (efi_early->is64)
		status = setup_uga64(uga_handle, size, &width, &height);
	else
		status = setup_uga32(uga_handle, size, &width, &height);

	if (!width && !height)
M
Matt Fleming 已提交
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
		goto free_handle;

	/* EFI framebuffer */
	si->orig_video_isVGA = VIDEO_TYPE_EFI;

	si->lfb_depth = 32;
	si->lfb_width = width;
	si->lfb_height = height;

	si->red_size = 8;
	si->red_pos = 16;
	si->green_size = 8;
	si->green_pos = 8;
	si->blue_size = 8;
	si->blue_pos = 0;
	si->rsvd_size = 8;
	si->rsvd_pos = 24;

free_handle:
575
	efi_call_early(free_pool, uga_handle);
M
Matt Fleming 已提交
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
	return status;
}

void setup_graphics(struct boot_params *boot_params)
{
	efi_guid_t graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
	struct screen_info *si;
	efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
	efi_status_t status;
	unsigned long size;
	void **gop_handle = NULL;
	void **uga_handle = NULL;

	si = &boot_params->screen_info;
	memset(si, 0, sizeof(*si));

	size = 0;
593 594 595
	status = efi_call_early(locate_handle,
				EFI_LOCATE_BY_PROTOCOL,
				&graphics_proto, NULL, &size, gop_handle);
M
Matt Fleming 已提交
596
	if (status == EFI_BUFFER_TOO_SMALL)
597
		status = efi_setup_gop(NULL, si, &graphics_proto, size);
M
Matt Fleming 已提交
598 599 600

	if (status != EFI_SUCCESS) {
		size = 0;
601 602 603
		status = efi_call_early(locate_handle,
					EFI_LOCATE_BY_PROTOCOL,
					&uga_proto, NULL, &size, uga_handle);
M
Matt Fleming 已提交
604 605 606 607 608 609 610 611 612
		if (status == EFI_BUFFER_TOO_SMALL)
			setup_uga(si, &uga_proto, size);
	}
}

/*
 * Because the x86 boot code expects to be passed a boot_params we
 * need to create one ourselves (usually the bootloader would create
 * one for us).
613 614 615
 *
 * The caller is responsible for filling out ->code32_start in the
 * returned boot_params.
M
Matt Fleming 已提交
616
 */
617
struct boot_params *make_boot_params(struct efi_config *c)
M
Matt Fleming 已提交
618
{
M
Matt Fleming 已提交
619 620 621 622
	struct boot_params *boot_params;
	struct apm_bios_info *bi;
	struct setup_header *hdr;
	efi_loaded_image_t *image;
623
	void *options, *handle;
M
Matt Fleming 已提交
624
	efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
M
Matt Fleming 已提交
625 626
	int options_size = 0;
	efi_status_t status;
627
	char *cmdline_ptr;
M
Matt Fleming 已提交
628 629 630
	u16 *s2;
	u8 *s1;
	int i;
631 632
	unsigned long ramdisk_addr;
	unsigned long ramdisk_size;
M
Matt Fleming 已提交
633

634 635 636
	efi_early = c;
	sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
	handle = (void *)(unsigned long)efi_early->image_handle;
M
Matt Fleming 已提交
637 638 639 640 641

	/* Check if we were booted by the EFI firmware */
	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
		return NULL;

642 643 644 645 646
	if (efi_early->is64)
		setup_boot_services64(efi_early);
	else
		setup_boot_services32(efi_early);

647 648
	status = efi_call_early(handle_protocol, handle,
				&proto, (void *)&image);
M
Matt Fleming 已提交
649
	if (status != EFI_SUCCESS) {
650
		efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
M
Matt Fleming 已提交
651 652 653
		return NULL;
	}

654 655
	status = efi_low_alloc(sys_table, 0x4000, 1,
			       (unsigned long *)&boot_params);
M
Matt Fleming 已提交
656
	if (status != EFI_SUCCESS) {
657
		efi_printk(sys_table, "Failed to alloc lowmem for boot params\n");
M
Matt Fleming 已提交
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
		return NULL;
	}

	memset(boot_params, 0x0, 0x4000);

	hdr = &boot_params->hdr;
	bi = &boot_params->apm_bios_info;

	/* Copy the second sector to boot_params */
	memcpy(&hdr->jump, image->image_base + 512, 512);

	/*
	 * Fill out some of the header fields ourselves because the
	 * EFI firmware loader doesn't load the first sector.
	 */
	hdr->root_flags = 1;
	hdr->vid_mode = 0xffff;
	hdr->boot_flag = 0xAA55;

M
Matt Fleming 已提交
677 678 679
	hdr->type_of_loader = 0x21;

	/* Convert unicode cmdline to ascii */
680
	cmdline_ptr = efi_convert_cmdline(sys_table, image, &options_size);
681 682 683
	if (!cmdline_ptr)
		goto fail;
	hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
684 685
	/* Fill in upper bits of command line address, NOP on 32 bit  */
	boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32;
M
Matt Fleming 已提交
686 687 688 689 690 691 692

	hdr->ramdisk_image = 0;
	hdr->ramdisk_size = 0;

	/* Clear APM BIOS info */
	memset(bi, 0, sizeof(*bi));

693 694 695 696
	status = efi_parse_options(cmdline_ptr);
	if (status != EFI_SUCCESS)
		goto fail2;

697 698
	status = handle_cmdline_files(sys_table, image,
				      (char *)(unsigned long)hdr->cmd_line_ptr,
699
				      "initrd=", hdr->initrd_addr_max,
700
				      &ramdisk_addr, &ramdisk_size);
701 702 703 704 705 706 707 708 709 710

	if (status != EFI_SUCCESS &&
	    hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) {
		efi_printk(sys_table, "Trying to load files to higher address\n");
		status = handle_cmdline_files(sys_table, image,
				      (char *)(unsigned long)hdr->cmd_line_ptr,
				      "initrd=", -1UL,
				      &ramdisk_addr, &ramdisk_size);
	}

M
Matt Fleming 已提交
711 712
	if (status != EFI_SUCCESS)
		goto fail2;
713 714 715 716
	hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
	hdr->ramdisk_size  = ramdisk_size & 0xffffffff;
	boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
	boot_params->ext_ramdisk_size  = (u64)ramdisk_size >> 32;
M
Matt Fleming 已提交
717 718 719

	return boot_params;
fail2:
720
	efi_free(sys_table, options_size, hdr->cmd_line_ptr);
M
Matt Fleming 已提交
721
fail:
722
	efi_free(sys_table, 0x4000, (unsigned long)boot_params);
M
Matt Fleming 已提交
723 724 725
	return NULL;
}

726 727
static void add_e820ext(struct boot_params *params,
			struct setup_data *e820ext, u32 nr_entries)
M
Matt Fleming 已提交
728
{
729
	struct setup_data *data;
M
Matt Fleming 已提交
730
	efi_status_t status;
731
	unsigned long size;
M
Matt Fleming 已提交
732

733
	e820ext->type = SETUP_E820_EXT;
734
	e820ext->len = nr_entries * sizeof(struct boot_e820_entry);
735
	e820ext->next = 0;
M
Matt Fleming 已提交
736

737
	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
M
Matt Fleming 已提交
738

739 740
	while (data && data->next)
		data = (struct setup_data *)(unsigned long)data->next;
741

742 743 744 745 746
	if (data)
		data->next = (unsigned long)e820ext;
	else
		params->hdr.setup_data = (unsigned long)e820ext;
}
M
Matt Fleming 已提交
747

748 749 750
static efi_status_t setup_e820(struct boot_params *params,
			       struct setup_data *e820ext, u32 e820ext_size)
{
751
	struct boot_e820_entry *entry = params->e820_table;
752
	struct efi_info *efi = &params->efi_info;
753
	struct boot_e820_entry *prev = NULL;
754 755 756
	u32 nr_entries;
	u32 nr_desc;
	int i;
M
Matt Fleming 已提交
757 758

	nr_entries = 0;
759 760 761
	nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;

	for (i = 0; i < nr_desc; i++) {
M
Matt Fleming 已提交
762 763
		efi_memory_desc_t *d;
		unsigned int e820_type = 0;
764
		unsigned long m = efi->efi_memmap;
M
Matt Fleming 已提交
765

766 767 768 769
#ifdef CONFIG_X86_64
		m |= (u64)efi->efi_memmap_hi << 32;
#endif

770
		d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
M
Matt Fleming 已提交
771 772 773 774 775 776 777
		switch (d->type) {
		case EFI_RESERVED_TYPE:
		case EFI_RUNTIME_SERVICES_CODE:
		case EFI_RUNTIME_SERVICES_DATA:
		case EFI_MEMORY_MAPPED_IO:
		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
		case EFI_PAL_CODE:
778
			e820_type = E820_TYPE_RESERVED;
M
Matt Fleming 已提交
779 780 781
			break;

		case EFI_UNUSABLE_MEMORY:
782
			e820_type = E820_TYPE_UNUSABLE;
M
Matt Fleming 已提交
783 784 785
			break;

		case EFI_ACPI_RECLAIM_MEMORY:
786
			e820_type = E820_TYPE_ACPI;
M
Matt Fleming 已提交
787 788 789 790 791 792 793
			break;

		case EFI_LOADER_CODE:
		case EFI_LOADER_DATA:
		case EFI_BOOT_SERVICES_CODE:
		case EFI_BOOT_SERVICES_DATA:
		case EFI_CONVENTIONAL_MEMORY:
794
			e820_type = E820_TYPE_RAM;
M
Matt Fleming 已提交
795 796 797
			break;

		case EFI_ACPI_MEMORY_NVS:
798
			e820_type = E820_TYPE_NVS;
M
Matt Fleming 已提交
799 800
			break;

801
		case EFI_PERSISTENT_MEMORY:
802
			e820_type = E820_TYPE_PMEM;
803 804
			break;

M
Matt Fleming 已提交
805 806 807 808 809 810
		default:
			continue;
		}

		/* Merge adjacent mappings */
		if (prev && prev->type == e820_type &&
811
		    (prev->addr + prev->size) == d->phys_addr) {
M
Matt Fleming 已提交
812
			prev->size += d->num_pages << 12;
813
			continue;
M
Matt Fleming 已提交
814
		}
815

816
		if (nr_entries == ARRAY_SIZE(params->e820_table)) {
817
			u32 need = (nr_desc - i) * sizeof(struct e820_entry) +
818 819 820 821 822 823
				   sizeof(struct setup_data);

			if (!e820ext || e820ext_size < need)
				return EFI_BUFFER_TOO_SMALL;

			/* boot_params map full, switch to e820 extended */
824
			entry = (struct boot_e820_entry *)e820ext->data;
825 826
		}

827 828 829 830
		entry->addr = d->phys_addr;
		entry->size = d->num_pages << PAGE_SHIFT;
		entry->type = e820_type;
		prev = entry++;
831
		nr_entries++;
M
Matt Fleming 已提交
832 833
	}

834 835
	if (nr_entries > ARRAY_SIZE(params->e820_table)) {
		u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_table);
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852

		add_e820ext(params, e820ext, nr_e820ext);
		nr_entries -= nr_e820ext;
	}

	params->e820_entries = (u8)nr_entries;

	return EFI_SUCCESS;
}

static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
				  u32 *e820ext_size)
{
	efi_status_t status;
	unsigned long size;

	size = sizeof(struct setup_data) +
853
		sizeof(struct e820_entry) * nr_desc;
854 855

	if (*e820ext) {
856
		efi_call_early(free_pool, *e820ext);
857 858 859 860
		*e820ext = NULL;
		*e820ext_size = 0;
	}

861 862
	status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
				size, (void **)e820ext);
863 864 865 866 867 868
	if (status == EFI_SUCCESS)
		*e820ext_size = size;

	return status;
}

869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
struct exit_boot_struct {
	struct boot_params *boot_params;
	struct efi_info *efi;
	struct setup_data *e820ext;
	__u32 e820ext_size;
	bool is64;
};

static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
				   struct efi_boot_memmap *map,
				   void *priv)
{
	static bool first = true;
	const char *signature;
	__u32 nr_desc;
	efi_status_t status;
	struct exit_boot_struct *p = priv;

	if (first) {
		nr_desc = *map->buff_size / *map->desc_size;
889
		if (nr_desc > ARRAY_SIZE(p->boot_params->e820_table)) {
890
			u32 nr_e820ext = nr_desc -
891
					ARRAY_SIZE(p->boot_params->e820_table);
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917

			status = alloc_e820ext(nr_e820ext, &p->e820ext,
					       &p->e820ext_size);
			if (status != EFI_SUCCESS)
				return status;
		}
		first = false;
	}

	signature = p->is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE;
	memcpy(&p->efi->efi_loader_signature, signature, sizeof(__u32));

	p->efi->efi_systab = (unsigned long)sys_table_arg;
	p->efi->efi_memdesc_size = *map->desc_size;
	p->efi->efi_memdesc_version = *map->desc_ver;
	p->efi->efi_memmap = (unsigned long)*map->map;
	p->efi->efi_memmap_size = *map->map_size;

#ifdef CONFIG_X86_64
	p->efi->efi_systab_hi = (unsigned long)sys_table_arg >> 32;
	p->efi->efi_memmap_hi = (unsigned long)*map->map >> 32;
#endif

	return EFI_SUCCESS;
}

918
static efi_status_t exit_boot(struct boot_params *boot_params,
919
			      void *handle, bool is64)
920
{
921
	unsigned long map_sz, key, desc_size, buff_size;
922 923 924 925 926
	efi_memory_desc_t *mem_map;
	struct setup_data *e820ext;
	__u32 e820ext_size;
	efi_status_t status;
	__u32 desc_version;
927
	struct efi_boot_memmap map;
928 929 930 931 932 933 934 935 936 937 938 939 940
	struct exit_boot_struct priv;

	map.map =		&mem_map;
	map.map_size =		&map_sz;
	map.desc_size =		&desc_size;
	map.desc_ver =		&desc_version;
	map.key_ptr =		&key;
	map.buff_size =		&buff_size;
	priv.boot_params =	boot_params;
	priv.efi =		&boot_params->efi_info;
	priv.e820ext =		NULL;
	priv.e820ext_size =	0;
	priv.is64 =		is64;
941

942 943 944
	/* Might as well exit boot services now */
	status = efi_exit_boot_services(sys_table, handle, &map, &priv,
					exit_boot_func);
945 946 947
	if (status != EFI_SUCCESS)
		return status;

948 949
	e820ext = priv.e820ext;
	e820ext_size = priv.e820ext_size;
950 951 952 953 954 955
	/* Historic? */
	boot_params->alt_mem_k = 32 * 1024;

	status = setup_e820(boot_params, e820ext, e820ext_size);
	if (status != EFI_SUCCESS)
		return status;
M
Matt Fleming 已提交
956 957 958 959

	return EFI_SUCCESS;
}

M
Matt Fleming 已提交
960 961 962 963
/*
 * On success we return a pointer to a boot_params structure, and NULL
 * on failure.
 */
964
struct boot_params *efi_main(struct efi_config *c,
M
Matt Fleming 已提交
965 966
			     struct boot_params *boot_params)
{
967
	struct desc_ptr *gdt = NULL;
M
Matt Fleming 已提交
968 969 970 971
	efi_loaded_image_t *image;
	struct setup_header *hdr = &boot_params->hdr;
	efi_status_t status;
	struct desc_struct *desc;
972 973 974 975 976 977 978 979 980
	void *handle;
	efi_system_table_t *_table;
	bool is64;

	efi_early = c;

	_table = (efi_system_table_t *)(unsigned long)efi_early->table;
	handle = (void *)(unsigned long)efi_early->image_handle;
	is64 = efi_early->is64;
M
Matt Fleming 已提交
981 982 983 984 985 986 987

	sys_table = _table;

	/* Check if we were booted by the EFI firmware */
	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
		goto fail;

988 989 990 991 992
	if (is64)
		setup_boot_services64(efi_early);
	else
		setup_boot_services32(efi_early);

993 994 995 996 997 998 999
	/*
	 * If the boot loader gave us a value for secure_boot then we use that,
	 * otherwise we ask the BIOS.
	 */
	if (boot_params->secure_boot == efi_secureboot_mode_unset)
		boot_params->secure_boot = efi_get_secureboot(sys_table);

M
Matt Fleming 已提交
1000
	setup_graphics(boot_params);
M
Matt Fleming 已提交
1001

1002
	setup_efi_pci(boot_params);
1003

1004 1005
	setup_quirks(boot_params);

1006 1007
	status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
				sizeof(*gdt), (void **)&gdt);
1008
	if (status != EFI_SUCCESS) {
1009
		efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
M
Matt Fleming 已提交
1010
		goto fail;
1011
	}
M
Matt Fleming 已提交
1012 1013

	gdt->size = 0x800;
1014
	status = efi_low_alloc(sys_table, gdt->size, 8,
1015
			   (unsigned long *)&gdt->address);
1016
	if (status != EFI_SUCCESS) {
1017
		efi_printk(sys_table, "Failed to alloc mem for gdt\n");
M
Matt Fleming 已提交
1018
		goto fail;
1019
	}
M
Matt Fleming 已提交
1020

M
Matt Fleming 已提交
1021 1022 1023 1024 1025
	/*
	 * If the kernel isn't already loaded at the preferred load
	 * address, relocate it.
	 */
	if (hdr->pref_address != hdr->code32_start) {
1026 1027 1028 1029 1030
		unsigned long bzimage_addr = hdr->code32_start;
		status = efi_relocate_kernel(sys_table, &bzimage_addr,
					     hdr->init_size, hdr->init_size,
					     hdr->pref_address,
					     hdr->kernel_alignment);
1031 1032
		if (status != EFI_SUCCESS) {
			efi_printk(sys_table, "efi_relocate_kernel() failed!\n");
M
Matt Fleming 已提交
1033
			goto fail;
1034
		}
1035 1036 1037

		hdr->pref_address = hdr->code32_start;
		hdr->code32_start = bzimage_addr;
M
Matt Fleming 已提交
1038 1039
	}

1040
	status = exit_boot(boot_params, handle, is64);
1041 1042
	if (status != EFI_SUCCESS) {
		efi_printk(sys_table, "exit_boot() failed!\n");
M
Matt Fleming 已提交
1043
		goto fail;
1044
	}
M
Matt Fleming 已提交
1045 1046 1047 1048

	memset((char *)gdt->address, 0x0, gdt->size);
	desc = (struct desc_struct *)gdt->address;

1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
	/* The first GDT is a dummy. */
	desc++;

	if (IS_ENABLED(CONFIG_X86_64)) {
		/* __KERNEL32_CS */
		desc->limit0 = 0xffff;
		desc->base0 = 0x0000;
		desc->base1 = 0x0000;
		desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
		desc->s = DESC_TYPE_CODE_DATA;
		desc->dpl = 0;
		desc->p = 1;
1061
		desc->limit1 = 0xf;
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
		desc->avl = 0;
		desc->l = 0;
		desc->d = SEG_OP_SIZE_32BIT;
		desc->g = SEG_GRANULARITY_4KB;
		desc->base2 = 0x00;
		desc++;
	} else {
		/* Second entry is unused on 32-bit */
		desc++;
	}
M
Matt Fleming 已提交
1072

1073
	/* __KERNEL_CS */
M
Matt Fleming 已提交
1074 1075 1076 1077 1078 1079 1080
	desc->limit0 = 0xffff;
	desc->base0 = 0x0000;
	desc->base1 = 0x0000;
	desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
	desc->s = DESC_TYPE_CODE_DATA;
	desc->dpl = 0;
	desc->p = 1;
1081
	desc->limit1 = 0xf;
M
Matt Fleming 已提交
1082
	desc->avl = 0;
1083 1084 1085 1086 1087 1088 1089
	if (IS_ENABLED(CONFIG_X86_64)) {
		desc->l = 1;
		desc->d = 0;
	} else {
		desc->l = 0;
		desc->d = SEG_OP_SIZE_32BIT;
	}
M
Matt Fleming 已提交
1090 1091 1092
	desc->g = SEG_GRANULARITY_4KB;
	desc->base2 = 0x00;
	desc++;
1093 1094

	/* __KERNEL_DS */
M
Matt Fleming 已提交
1095 1096 1097 1098 1099 1100 1101
	desc->limit0 = 0xffff;
	desc->base0 = 0x0000;
	desc->base1 = 0x0000;
	desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
	desc->s = DESC_TYPE_CODE_DATA;
	desc->dpl = 0;
	desc->p = 1;
1102
	desc->limit1 = 0xf;
M
Matt Fleming 已提交
1103 1104 1105 1106 1107 1108
	desc->avl = 0;
	desc->l = 0;
	desc->d = SEG_OP_SIZE_32BIT;
	desc->g = SEG_GRANULARITY_4KB;
	desc->base2 = 0x00;
	desc++;
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118

	if (IS_ENABLED(CONFIG_X86_64)) {
		/* Task segment value */
		desc->limit0 = 0x0000;
		desc->base0 = 0x0000;
		desc->base1 = 0x0000;
		desc->type = SEG_TYPE_TSS;
		desc->s = 0;
		desc->dpl = 0;
		desc->p = 1;
1119
		desc->limit1 = 0x0;
1120 1121 1122 1123 1124 1125 1126
		desc->avl = 0;
		desc->l = 0;
		desc->d = 0;
		desc->g = SEG_GRANULARITY_4KB;
		desc->base2 = 0x00;
		desc++;
	}
M
Matt Fleming 已提交
1127 1128

	asm volatile("cli");
1129
	asm volatile ("lgdt %0" : : "m" (*gdt));
M
Matt Fleming 已提交
1130 1131 1132

	return boot_params;
fail:
1133
	efi_printk(sys_table, "efi_main() failed!\n");
M
Matt Fleming 已提交
1134 1135
	return NULL;
}