1 /*
2  * Architecture specific implementation for EFI boot code.  This file
3  * is intended to be included by common/efi/boot.c _only_, and
4  * therefore can define arch specific global variables.
5  */
6 #include <xen/vga.h>
7 #include <asm/e820.h>
8 #include <asm/edd.h>
9 #include <asm/microcode.h>
10 #include <asm/msr.h>
11 #include <asm/setup.h>
12 
13 static struct file __initdata ucode;
14 static multiboot_info_t __initdata mbi = {
15     .flags = MBI_MODULES | MBI_LOADERNAME
16 };
17 /*
18  * The array size needs to be one larger than the number of modules we
19  * support - see __start_xen().
20  */
21 static module_t __initdata mb_modules[5];
22 
edd_put_string(u8 * dst,size_t n,const char * src)23 static void __init edd_put_string(u8 *dst, size_t n, const char *src)
24 {
25     while ( n-- && *src )
26        *dst++ = *src++;
27     if ( *src )
28        PrintErrMesg(L"Internal error populating EDD info",
29                     EFI_BUFFER_TOO_SMALL);
30     while ( n-- )
31        *dst++ = ' ';
32 }
33 #define edd_put_string(d, s) edd_put_string(d, ARRAY_SIZE(d), s)
34 
35 extern const intpte_t __page_tables_start[], __page_tables_end[];
36 #define in_page_tables(v) ((intpte_t *)(v) >= __page_tables_start && \
37                            (intpte_t *)(v) < __page_tables_end)
38 
39 #define PE_BASE_RELOC_ABS      0
40 #define PE_BASE_RELOC_HIGHLOW  3
41 #define PE_BASE_RELOC_DIR64   10
42 
43 extern const struct pe_base_relocs {
44     u32 rva;
45     u32 size;
46     u16 entries[];
47 } __base_relocs_start[], __base_relocs_end[];
48 
efi_arch_relocate_image(unsigned long delta)49 static void __init efi_arch_relocate_image(unsigned long delta)
50 {
51     const struct pe_base_relocs *base_relocs;
52 
53     for ( base_relocs = __base_relocs_start; base_relocs < __base_relocs_end; )
54     {
55         unsigned int i = 0, n;
56 
57         n = (base_relocs->size - sizeof(*base_relocs)) /
58             sizeof(*base_relocs->entries);
59 
60         /*
61          * Relevant l{2,3}_bootmap entries get initialized explicitly in
62          * efi_arch_memory_setup(), so we must not apply relocations there.
63          * l2_directmap's first slot, otoh, should be handled normally, as
64          * efi_arch_memory_setup() won't touch it (xen_phys_start should
65          * never be zero).
66          */
67         if ( xen_phys_start + base_relocs->rva == (unsigned long)l3_bootmap ||
68              xen_phys_start + base_relocs->rva == (unsigned long)l2_bootmap )
69             i = n;
70 
71         for ( ; i < n; ++i )
72         {
73             unsigned long addr = xen_phys_start + base_relocs->rva +
74                                  (base_relocs->entries[i] & 0xfff);
75 
76             switch ( base_relocs->entries[i] >> 12 )
77             {
78             case PE_BASE_RELOC_ABS:
79                 break;
80             case PE_BASE_RELOC_HIGHLOW:
81                 if ( delta )
82                 {
83                     *(u32 *)addr += delta;
84                     if ( in_page_tables(addr) )
85                         *(u32 *)addr += xen_phys_start;
86                 }
87                 break;
88             case PE_BASE_RELOC_DIR64:
89                 if ( delta )
90                 {
91                     *(u64 *)addr += delta;
92                     if ( in_page_tables(addr) )
93                         *(u64 *)addr += xen_phys_start;
94                 }
95                 break;
96             default:
97                 blexit(L"Unsupported relocation type");
98             }
99         }
100         base_relocs = (const void *)(base_relocs->entries + i + (i & 1));
101     }
102 }
103 
104 extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
105 extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
106 
relocate_trampoline(unsigned long phys)107 static void __init relocate_trampoline(unsigned long phys)
108 {
109     const s32 *trampoline_ptr;
110 
111     trampoline_phys = phys;
112 
113     if ( !efi_enabled(EFI_LOADER) )
114         return;
115 
116     /* Apply relocations to trampoline. */
117     for ( trampoline_ptr = __trampoline_rel_start;
118           trampoline_ptr < __trampoline_rel_stop;
119           ++trampoline_ptr )
120         *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
121     for ( trampoline_ptr = __trampoline_seg_start;
122           trampoline_ptr < __trampoline_seg_stop;
123           ++trampoline_ptr )
124         *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
125 }
126 
place_string(u32 * addr,const char * s)127 static void __init place_string(u32 *addr, const char *s)
128 {
129     char *alloc = NULL;
130 
131     if ( s && *s )
132     {
133         size_t len1 = strlen(s) + 1;
134         const char *old = (char *)(long)*addr;
135         size_t len2 = *addr ? strlen(old) + 1 : 0;
136 
137         alloc = ebmalloc(len1 + len2);
138         /*
139          * Insert new string before already existing one. This is needed
140          * for options passed on the command line to override options from
141          * the configuration file.
142          */
143         memcpy(alloc, s, len1);
144         if ( *addr )
145         {
146             alloc[len1 - 1] = ' ';
147             memcpy(alloc + len1, old, len2);
148         }
149     }
150     *addr = (long)alloc;
151 }
152 
efi_arch_process_memory_map(EFI_SYSTEM_TABLE * SystemTable,void * map,UINTN map_size,UINTN desc_size,UINT32 desc_ver)153 static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
154                                                void *map,
155                                                UINTN map_size,
156                                                UINTN desc_size,
157                                                UINT32 desc_ver)
158 {
159     struct e820entry *e;
160     unsigned int i;
161 
162     /* Populate E820 table and check trampoline area availability. */
163     e = e820_raw.map - 1;
164     for ( e820_raw.nr_map = i = 0; i < map_size; i += desc_size )
165     {
166         EFI_MEMORY_DESCRIPTOR *desc = map + i;
167         u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
168         u32 type;
169 
170         switch ( desc->Type )
171         {
172         default:
173             type = E820_RESERVED;
174             break;
175 
176         case EfiBootServicesCode:
177         case EfiBootServicesData:
178             if ( map_bs )
179             {
180                 type = E820_RESERVED;
181                 break;
182             }
183             fallthrough;
184         case EfiConventionalMemory:
185             if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
186                  len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
187                 cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
188             fallthrough;
189         case EfiLoaderCode:
190         case EfiLoaderData:
191             if ( desc->Attribute & EFI_MEMORY_RUNTIME )
192                 type = E820_RESERVED;
193             else if ( desc->Attribute & EFI_MEMORY_WB )
194                 type = E820_RAM;
195             else
196                 type = E820_UNUSABLE;
197             break;
198 
199         case EfiUnusableMemory:
200             type = E820_UNUSABLE;
201             break;
202 
203         case EfiACPIReclaimMemory:
204             type = E820_ACPI;
205             break;
206         case EfiACPIMemoryNVS:
207             type = E820_NVS;
208             break;
209         }
210         if ( e820_raw.nr_map && type == e->type &&
211              desc->PhysicalStart == e->addr + e->size )
212             e->size += len;
213         else if ( !len || e820_raw.nr_map >= ARRAY_SIZE(e820_raw.map) )
214             continue;
215         else
216         {
217             ++e;
218             e->addr = desc->PhysicalStart;
219             e->size = len;
220             e->type = type;
221             ++e820_raw.nr_map;
222         }
223     }
224 
225 }
226 
efi_arch_allocate_mmap_buffer(UINTN map_size)227 static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
228 {
229     return ebmalloc(map_size);
230 }
231 
efi_arch_pre_exit_boot(void)232 static void __init efi_arch_pre_exit_boot(void)
233 {
234     if ( !trampoline_phys )
235     {
236         if ( !cfg.addr )
237             blexit(L"No memory for trampoline");
238         relocate_trampoline(cfg.addr);
239     }
240 }
241 
efi_arch_post_exit_boot(void)242 static void __init noreturn efi_arch_post_exit_boot(void)
243 {
244     u64 cr4 = XEN_MINIMAL_CR4 & ~X86_CR4_PGE, efer;
245 
246     efi_arch_relocate_image(__XEN_VIRT_START - xen_phys_start);
247     memcpy((void *)trampoline_phys, trampoline_start, cfg.size);
248 
249     /* Set system registers and transfer control. */
250     asm volatile("pushq $0\n\tpopfq");
251     rdmsrl(MSR_EFER, efer);
252     efer |= trampoline_efer;
253     wrmsrl(MSR_EFER, efer);
254     wrmsrl(MSR_IA32_CR_PAT, XEN_MSR_PAT);
255     write_cr0(X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP |
256               X86_CR0_AM | X86_CR0_PG);
257     asm volatile ( "mov    %[cr4], %%cr4\n\t"
258                    "mov    %[cr3], %%cr3\n\t"
259 #if XEN_MINIMAL_CR4 & X86_CR4_PGE
260                    "or     $"__stringify(X86_CR4_PGE)", %[cr4]\n\t"
261                    "mov    %[cr4], %%cr4\n\t"
262 #endif
263                    "lgdt   boot_gdtr(%%rip)\n\t"
264                    "mov    %[ds], %%ss\n\t"
265                    "mov    %[ds], %%ds\n\t"
266                    "mov    %[ds], %%es\n\t"
267                    "mov    %[ds], %%fs\n\t"
268                    "mov    %[ds], %%gs\n\t"
269 
270                    /* Jump to higher mappings. */
271                    "mov    stack_start(%%rip), %%rsp\n\t"
272                    "movabs $__start_xen, %[rip]\n\t"
273                    "push   %[cs]\n\t"
274                    "push   %[rip]\n\t"
275                    "lretq"
276                    : [rip] "=&r" (efer/* any dead 64-bit variable */),
277                      [cr4] "+&r" (cr4)
278                    : [cr3] "r" (idle_pg_table),
279                      [cs] "i" (__HYPERVISOR_CS),
280                      [ds] "r" (__HYPERVISOR_DS),
281                      "D" (&mbi)
282                    : "memory" );
283     unreachable();
284 }
285 
efi_arch_cfg_file_early(const EFI_LOADED_IMAGE * image,EFI_FILE_HANDLE dir_handle,const char * section)286 static void __init efi_arch_cfg_file_early(const EFI_LOADED_IMAGE *image,
287                                            EFI_FILE_HANDLE dir_handle,
288                                            const char *section)
289 {
290 }
291 
efi_arch_cfg_file_late(const EFI_LOADED_IMAGE * image,EFI_FILE_HANDLE dir_handle,const char * section)292 static void __init efi_arch_cfg_file_late(const EFI_LOADED_IMAGE *image,
293                                           EFI_FILE_HANDLE dir_handle,
294                                           const char *section)
295 {
296     union string name;
297 
298     if ( read_section(image, L"ucode", &ucode, NULL) )
299         return;
300 
301     name.s = get_value(&cfg, section, "ucode");
302     if ( !name.s )
303         name.s = get_value(&cfg, "global", "ucode");
304     if ( name.s )
305     {
306         microcode_set_module(mbi.mods_count);
307         split_string(name.s);
308         read_file(dir_handle, s2w(&name), &ucode, NULL);
309         efi_bs->FreePool(name.w);
310     }
311 }
312 
efi_arch_handle_cmdline(CHAR16 * cmdline_options,const char * cfgfile_options)313 static void __init efi_arch_handle_cmdline(CHAR16 *cmdline_options,
314                                            const char *cfgfile_options)
315 {
316     union string name;
317 
318     /* NB place_string() prepends, so call in reverse order. */
319     if ( cmdline_options )
320     {
321         name.w = cmdline_options;
322         w2s(&name);
323         place_string(&mbi.cmdline, name.s);
324     }
325     if ( cfgfile_options )
326         place_string(&mbi.cmdline, cfgfile_options);
327 
328     if ( mbi.cmdline )
329         mbi.flags |= MBI_CMDLINE;
330     /*
331      * These must not be initialized statically, since the value must
332      * not get relocated when processing base relocations later.
333      */
334     mbi.boot_loader_name = (long)"EFI";
335     mbi.mods_addr = (long)mb_modules;
336 }
337 
efi_arch_edd(void)338 static void __init efi_arch_edd(void)
339 {
340     static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
341     static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
342     EFI_HANDLE *handles = NULL;
343     unsigned int i;
344     UINTN size;
345     EFI_STATUS status;
346 
347     /* Collect EDD info. */
348     BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
349     BUILD_BUG_ON(sizeof(struct edd_device_params) != EDDPARMSIZE);
350     size = 0;
351     status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size, NULL);
352     if ( status == EFI_BUFFER_TOO_SMALL )
353         status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
354     if ( !EFI_ERROR(status) )
355         status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size,
356                                       handles);
357     if ( EFI_ERROR(status) )
358         size = 0;
359     for ( i = 0; i < size / sizeof(*handles); ++i )
360     {
361         EFI_BLOCK_IO *bio;
362         EFI_DEV_PATH_PTR devp;
363         struct edd_info *info = boot_edd_info + boot_edd_info_nr;
364         struct edd_device_params *params = &info->edd_device_params;
365         enum { root, acpi, pci, ctrlr } state = root;
366 
367         status = efi_bs->HandleProtocol(handles[i], &bio_guid, (void **)&bio);
368         if ( EFI_ERROR(status) ||
369              bio->Media->RemovableMedia ||
370              bio->Media->LogicalPartition )
371             continue;
372         if ( boot_edd_info_nr < EDD_INFO_MAX )
373         {
374             info->device = 0x80 + boot_edd_info_nr; /* fake */
375             info->version = 0x11;
376             params->length = offsetof(struct edd_device_params, dpte_ptr);
377             params->number_of_sectors = bio->Media->LastBlock + 1;
378             params->bytes_per_sector = bio->Media->BlockSize;
379             params->dpte_ptr = ~0;
380         }
381         ++boot_edd_info_nr;
382         status = efi_bs->HandleProtocol(handles[i], &devp_guid,
383                                         (void **)&devp);
384         if ( EFI_ERROR(status) )
385             continue;
386         for ( ; !IsDevicePathEnd(devp.DevPath);
387               devp.DevPath = NextDevicePathNode(devp.DevPath) )
388         {
389             switch ( DevicePathType(devp.DevPath) )
390             {
391                 const u8 *p;
392 
393             case ACPI_DEVICE_PATH:
394                 if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
395                     break;
396                 switch ( DevicePathSubType(devp.DevPath) )
397                 {
398                 case ACPI_DP:
399                     if ( devp.Acpi->HID != EISA_PNP_ID(0xA03) &&
400                          devp.Acpi->HID != EISA_PNP_ID(0xA08) )
401                         break;
402                     params->interface_path.pci.bus = devp.Acpi->UID;
403                     state = acpi;
404                     break;
405                 case EXPANDED_ACPI_DP:
406                     /* XXX */
407                     break;
408                 }
409                 break;
410             case HARDWARE_DEVICE_PATH:
411                 if ( state != acpi ||
412                      DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
413                      boot_edd_info_nr > EDD_INFO_MAX )
414                     break;
415                 state = pci;
416                 edd_put_string(params->host_bus_type, "PCI");
417                 params->interface_path.pci.slot = devp.Pci->Device;
418                 params->interface_path.pci.function = devp.Pci->Function;
419                 break;
420             case MESSAGING_DEVICE_PATH:
421                 if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
422                     break;
423                 state = ctrlr;
424                 switch ( DevicePathSubType(devp.DevPath) )
425                 {
426                 case MSG_ATAPI_DP:
427                     edd_put_string(params->interface_type, "ATAPI");
428                     params->interface_path.pci.channel =
429                         devp.Atapi->PrimarySecondary;
430                     params->device_path.atapi.device = devp.Atapi->SlaveMaster;
431                     params->device_path.atapi.lun = devp.Atapi->Lun;
432                     break;
433                 case MSG_SCSI_DP:
434                     edd_put_string(params->interface_type, "SCSI");
435                     params->device_path.scsi.id = devp.Scsi->Pun;
436                     params->device_path.scsi.lun = devp.Scsi->Lun;
437                     break;
438                 case MSG_FIBRECHANNEL_DP:
439                     edd_put_string(params->interface_type, "FIBRE");
440                     params->device_path.fibre.wwid = devp.FibreChannel->WWN;
441                     params->device_path.fibre.lun = devp.FibreChannel->Lun;
442                     break;
443                 case MSG_1394_DP:
444                     edd_put_string(params->interface_type, "1394");
445                     params->device_path.i1394.eui = devp.F1394->Guid;
446                     break;
447                 case MSG_USB_DP:
448                 case MSG_USB_CLASS_DP:
449                     edd_put_string(params->interface_type, "USB");
450                     break;
451                 case MSG_I2O_DP:
452                     edd_put_string(params->interface_type, "I2O");
453                     params->device_path.i2o.identity_tag = devp.I2O->Tid;
454                     break;
455                 default:
456                     continue;
457                 }
458                 info->version = 0x30;
459                 params->length = sizeof(struct edd_device_params);
460                 params->key = 0xbedd;
461                 params->device_path_info_length =
462                     sizeof(struct edd_device_params) -
463                     offsetof(struct edd_device_params, key);
464                 for ( p = (const u8 *)&params->key; p < &params->checksum; ++p )
465                     params->checksum -= *p;
466                 break;
467             case MEDIA_DEVICE_PATH:
468                 if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
469                      devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
470                      boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
471                 {
472                     struct mbr_signature *sig = boot_mbr_signature +
473                                                 boot_mbr_signature_nr;
474 
475                     sig->device = 0x80 + boot_edd_info_nr; /* fake */
476                     memcpy(&sig->signature, devp.HardDrive->Signature,
477                            sizeof(sig->signature));
478                     ++boot_mbr_signature_nr;
479                 }
480                 break;
481             }
482         }
483     }
484     if ( handles )
485         efi_bs->FreePool(handles);
486     if ( boot_edd_info_nr > EDD_INFO_MAX )
487         boot_edd_info_nr = EDD_INFO_MAX;
488 }
489 
efi_arch_console_init(UINTN cols,UINTN rows)490 static void __init efi_arch_console_init(UINTN cols, UINTN rows)
491 {
492 #ifdef CONFIG_VIDEO
493     vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
494     vga_console_info.u.text_mode_3.columns = cols;
495     vga_console_info.u.text_mode_3.rows = rows;
496     vga_console_info.u.text_mode_3.font_height = 16;
497 #endif
498 }
499 
efi_arch_video_init(EFI_GRAPHICS_OUTPUT_PROTOCOL * gop,UINTN info_size,EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * mode_info)500 static void __init efi_arch_video_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
501                                        UINTN info_size,
502                                        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info)
503 {
504 #ifdef CONFIG_VIDEO
505     int bpp = 0;
506 
507     if ( !gop->Mode->FrameBufferBase || !mode_info->HorizontalResolution ||
508          !mode_info->VerticalResolution )
509     {
510         PrintErr(L"Invalid Frame Buffer configuration found\r\n");
511         return;
512     }
513 
514     switch ( mode_info->PixelFormat )
515     {
516     case PixelRedGreenBlueReserved8BitPerColor:
517         vga_console_info.u.vesa_lfb.red_pos = 0;
518         vga_console_info.u.vesa_lfb.red_size = 8;
519         vga_console_info.u.vesa_lfb.green_pos = 8;
520         vga_console_info.u.vesa_lfb.green_size = 8;
521         vga_console_info.u.vesa_lfb.blue_pos = 16;
522         vga_console_info.u.vesa_lfb.blue_size = 8;
523         vga_console_info.u.vesa_lfb.rsvd_pos = 24;
524         vga_console_info.u.vesa_lfb.rsvd_size = 8;
525         bpp = 32;
526         break;
527     case PixelBlueGreenRedReserved8BitPerColor:
528         vga_console_info.u.vesa_lfb.red_pos = 16;
529         vga_console_info.u.vesa_lfb.red_size = 8;
530         vga_console_info.u.vesa_lfb.green_pos = 8;
531         vga_console_info.u.vesa_lfb.green_size = 8;
532         vga_console_info.u.vesa_lfb.blue_pos = 0;
533         vga_console_info.u.vesa_lfb.blue_size = 8;
534         vga_console_info.u.vesa_lfb.rsvd_pos = 24;
535         vga_console_info.u.vesa_lfb.rsvd_size = 8;
536         bpp = 32;
537         break;
538     case PixelBitMask:
539         bpp = set_color(mode_info->PixelInformation.RedMask, bpp,
540                         &vga_console_info.u.vesa_lfb.red_pos,
541                         &vga_console_info.u.vesa_lfb.red_size);
542         bpp = set_color(mode_info->PixelInformation.GreenMask, bpp,
543                         &vga_console_info.u.vesa_lfb.green_pos,
544                         &vga_console_info.u.vesa_lfb.green_size);
545         bpp = set_color(mode_info->PixelInformation.BlueMask, bpp,
546                         &vga_console_info.u.vesa_lfb.blue_pos,
547                         &vga_console_info.u.vesa_lfb.blue_size);
548         if ( mode_info->PixelInformation.ReservedMask )
549             bpp = set_color(mode_info->PixelInformation.ReservedMask, bpp,
550                             &vga_console_info.u.vesa_lfb.rsvd_pos,
551                             &vga_console_info.u.vesa_lfb.rsvd_size);
552         if ( bpp > 0 )
553             break;
554         /* fall through */
555     default:
556         PrintErr(L"Current graphics mode is unsupported!\r\n");
557         bpp  = 0;
558         break;
559     }
560     if ( bpp > 0 )
561     {
562         vga_console_info.video_type = XEN_VGATYPE_EFI_LFB;
563         vga_console_info.u.vesa_lfb.gbl_caps = 2; /* possibly non-VGA */
564         vga_console_info.u.vesa_lfb.width =
565             mode_info->HorizontalResolution;
566         vga_console_info.u.vesa_lfb.height = mode_info->VerticalResolution;
567         vga_console_info.u.vesa_lfb.bits_per_pixel = bpp;
568         vga_console_info.u.vesa_lfb.bytes_per_line =
569             (mode_info->PixelsPerScanLine * bpp + 7) >> 3;
570         vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
571         vga_console_info.u.vesa_lfb.ext_lfb_base = gop->Mode->FrameBufferBase >> 32;
572         vga_console_info.u.vesa_lfb.lfb_size =
573             (gop->Mode->FrameBufferSize + 0xffff) >> 16;
574     }
575 #endif
576 }
577 
578 #ifdef CONFIG_VIDEO
copy_edid(const void * buf,unsigned int size)579 static bool __init copy_edid(const void *buf, unsigned int size)
580 {
581     /*
582      * Be conservative - for both undersized and oversized blobs it is unclear
583      * what to actually do with them. The more that unlike the VESA BIOS
584      * interface we also have no associated "capabilities" value (which might
585      * carry a hint as to possible interpretation).
586      */
587     if ( size != ARRAY_SIZE(boot_edid_info) )
588         return false;
589 
590     memcpy(boot_edid_info, buf, size);
591     boot_edid_caps = 0;
592 
593     return true;
594 }
595 #endif
596 
efi_arch_edid(EFI_HANDLE gop_handle)597 static void __init efi_arch_edid(EFI_HANDLE gop_handle)
598 {
599 #ifdef CONFIG_VIDEO
600     static EFI_GUID __initdata active_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID;
601     static EFI_GUID __initdata discovered_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
602     EFI_EDID_ACTIVE_PROTOCOL *active_edid;
603     EFI_EDID_DISCOVERED_PROTOCOL *discovered_edid;
604     EFI_STATUS status;
605 
606     status = efi_bs->OpenProtocol(gop_handle, &active_guid,
607                                   (void **)&active_edid, efi_ih, NULL,
608                                   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
609     if ( status == EFI_SUCCESS &&
610          copy_edid(active_edid->Edid, active_edid->SizeOfEdid) )
611         return;
612 
613     /*
614      * In case an override is in place which doesn't fit copy_edid(), also try
615      * obtaining the discovered EDID in the hope that it's better than nothing.
616      *
617      * Note that attempting to use the information in
618      * EFI_EDID_DISCOVERED_PROTOCOL when there's an override provided by
619      * EFI_EDID_ACTIVE_PROTOCOL might lead to issues.
620      */
621     status = efi_bs->OpenProtocol(gop_handle, &discovered_guid,
622                                   (void **)&discovered_edid, efi_ih, NULL,
623                                   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
624     if ( status == EFI_SUCCESS )
625         copy_edid(discovered_edid->Edid, discovered_edid->SizeOfEdid);
626 #endif
627 }
628 
efi_arch_memory_setup(void)629 static void __init efi_arch_memory_setup(void)
630 {
631     unsigned int i;
632     EFI_STATUS status;
633 
634     /* Allocate space for trampoline (in first Mb). */
635     cfg.addr = 0x100000;
636 
637     if ( efi_enabled(EFI_LOADER) )
638         cfg.size = trampoline_end - trampoline_start;
639     else
640         cfg.size = TRAMPOLINE_SPACE + TRAMPOLINE_STACK_SPACE;
641 
642     status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
643                                    PFN_UP(cfg.size), &cfg.addr);
644     if ( status == EFI_SUCCESS )
645         relocate_trampoline(cfg.addr);
646     else
647     {
648         cfg.addr = 0;
649         PrintStr(L"Trampoline space cannot be allocated; will try fallback.\r\n");
650     }
651 
652     if ( !efi_enabled(EFI_LOADER) )
653         return;
654 
655     /*
656      * Map Xen into the higher mappings, using 2M superpages.
657      *
658      * NB: We are currently in physical mode, so a RIP-relative relocation
659      * against _start/_end result in our arbitrary placement by the bootloader
660      * in memory, rather than the intended high mappings position.  Subtract
661      * xen_phys_start to get the appropriate slots in l2_xenmap[].
662      */
663     for ( i =  l2_table_offset((UINTN)_start   - xen_phys_start);
664           i <= l2_table_offset((UINTN)_end - 1 - xen_phys_start); ++i )
665         l2_xenmap[i] =
666             l2e_from_paddr(xen_phys_start + (i << L2_PAGETABLE_SHIFT),
667                            PAGE_HYPERVISOR_RWX | _PAGE_PSE);
668 
669     /* Check that there is at least 4G of mapping space in l2_*map[] */
670     BUILD_BUG_ON((sizeof(l2_bootmap)   / L2_PAGETABLE_ENTRIES) < 4);
671     BUILD_BUG_ON((sizeof(l2_directmap) / L2_PAGETABLE_ENTRIES) < 4);
672 
673     /* Initialize L3 boot-map page directory entries. */
674     for ( i = 0; i < 4; ++i )
675         l3_bootmap[i] = l3e_from_paddr((UINTN)l2_bootmap + i * PAGE_SIZE,
676                                        __PAGE_HYPERVISOR);
677     /*
678      * Map Xen into the directmap (needed for early-boot pagetable
679      * handling/walking), and identity map Xen into bootmap (needed for the
680      * transition from the EFI pagetables to Xen), using 2M superpages.
681      *
682      * NB: We are currently in physical mode, so a RIP-relative relocation
683      * against _start/_end gets their real position in memory, which are the
684      * appropriate l2 slots to map.
685      */
686 #define l2_4G_offset(a)                                                 \
687     (((a) >> L2_PAGETABLE_SHIFT) & (4 * L2_PAGETABLE_ENTRIES - 1))
688 
689     for ( i  = l2_4G_offset((UINTN)_start);
690           i <= l2_4G_offset((UINTN)_end - 1); ++i )
691     {
692         l2_pgentry_t pte = l2e_from_paddr(i << L2_PAGETABLE_SHIFT,
693                                           __PAGE_HYPERVISOR | _PAGE_PSE);
694 
695         l2_bootmap[i] = pte;
696 
697         /* Bootmap RWX/Non-global.  Directmap RW/Global. */
698         l2e_add_flags(pte, PAGE_HYPERVISOR);
699 
700         l2_directmap[i] = pte;
701     }
702 #undef l2_4G_offset
703 }
704 
efi_arch_handle_module(const struct file * file,const CHAR16 * name,const char * options)705 static void __init efi_arch_handle_module(const struct file *file,
706                                           const CHAR16 *name,
707                                           const char *options)
708 {
709     union string local_name;
710     void *ptr;
711 
712     /*
713      * Make a copy, as conversion is destructive, and caller still wants
714      * wide string available after this call returns.
715      */
716     if ( efi_bs->AllocatePool(EfiLoaderData, (wstrlen(name) + 1) * sizeof(*name),
717                               &ptr) != EFI_SUCCESS )
718         blexit(L"Unable to allocate string buffer");
719 
720     local_name.w = ptr;
721     wstrcpy(local_name.w, name);
722     w2s(&local_name);
723 
724     /*
725      * If options are provided, put them in
726      * mb_modules[mbi.mods_count].string after the filename, with a space
727      * separating them.  place_string() prepends strings and adds separating
728      * spaces, so the call order is reversed.
729      */
730     if ( options )
731         place_string(&mb_modules[mbi.mods_count].string, options);
732     place_string(&mb_modules[mbi.mods_count].string, local_name.s);
733     mb_modules[mbi.mods_count].mod_start = file->addr >> PAGE_SHIFT;
734     mb_modules[mbi.mods_count].mod_end = file->size;
735     ++mbi.mods_count;
736     efi_bs->FreePool(ptr);
737 }
738 
efi_arch_cpu(void)739 static void __init efi_arch_cpu(void)
740 {
741     uint32_t eax = cpuid_eax(0x80000000U);
742     uint32_t *caps = boot_cpu_data.x86_capability;
743 
744     boot_tsc_stamp = rdtsc();
745 
746     caps[FEATURESET_1c] = cpuid_ecx(1);
747 
748     if ( (eax >> 16) == 0x8000 && eax > 0x80000000U )
749     {
750         caps[FEATURESET_e1d] = cpuid_edx(0x80000001U);
751 
752         /*
753          * This check purposefully doesn't use cpu_has_nx because
754          * cpu_has_nx bypasses the boot_cpu_data read if Xen was compiled
755          * with CONFIG_REQUIRE_NX
756          */
757         if ( IS_ENABLED(CONFIG_REQUIRE_NX) &&
758              !boot_cpu_has(X86_FEATURE_NX) )
759             blexit(L"This build of Xen requires NX support");
760 
761         if ( cpu_has_nx )
762             trampoline_efer |= EFER_NXE;
763     }
764 }
765 
efi_arch_blexit(void)766 static void __init efi_arch_blexit(void)
767 {
768     if ( ucode.need_to_free )
769         efi_bs->FreePages(ucode.addr, PFN_UP(ucode.size));
770 }
771 
efi_arch_halt(void)772 static void __init efi_arch_halt(void)
773 {
774     local_irq_disable();
775     for ( ; ; )
776         halt();
777 }
778 
efi_arch_load_addr_check(const EFI_LOADED_IMAGE * loaded_image)779 static void __init efi_arch_load_addr_check(const EFI_LOADED_IMAGE *loaded_image)
780 {
781     xen_phys_start = (UINTN)loaded_image->ImageBase;
782     if ( (xen_phys_start + loaded_image->ImageSize - 1) >> 32 )
783         blexit(L"Xen must be loaded below 4Gb.");
784     if ( xen_phys_start & ((1 << L2_PAGETABLE_SHIFT) - 1) )
785         blexit(L"Xen must be loaded at a 2Mb boundary.");
786     trampoline_xen_phys_start = xen_phys_start;
787 }
788 
efi_arch_use_config_file(EFI_SYSTEM_TABLE * SystemTable)789 static bool __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
790 {
791     return true; /* x86 always uses a config file */
792 }
793 
efi_arch_flush_dcache_area(const void * vaddr,UINTN size)794 static void __init efi_arch_flush_dcache_area(const void *vaddr, UINTN size) { }
795 
796 /* Return a pointer to the character after the first occurrence of opt in cmd */
get_option(const char * cmd,const char * opt)797 static const char *__init get_option(const char *cmd, const char *opt)
798 {
799     const char *s = cmd, *o = NULL;
800 
801     if ( !cmd || !opt )
802         return NULL;
803 
804     while ( (s = strstr(s, opt)) != NULL )
805     {
806         if ( s == cmd || *(s - 1) == ' ' || *(s - 1) == '\t' )
807         {
808             o = s + strlen(opt);
809             break;
810         }
811 
812         s += strlen(opt);
813     }
814 
815     return o;
816 }
817 
efi_multiboot2(EFI_HANDLE ImageHandle,EFI_SYSTEM_TABLE * SystemTable,const char * cmdline)818 void asmlinkage __init efi_multiboot2(EFI_HANDLE ImageHandle,
819                                       EFI_SYSTEM_TABLE *SystemTable,
820                                       const char *cmdline)
821 {
822     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
823     EFI_HANDLE gop_handle;
824     UINTN cols, gop_mode = ~0, rows;
825 
826     __set_bit(EFI_BOOT, &efi_flags);
827     __set_bit(EFI_RS, &efi_flags);
828 
829     efi_init(ImageHandle, SystemTable);
830 
831     if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
832                            &cols, &rows) != EFI_SUCCESS )
833         /*
834          * If active StdOut mode is invalid init ConOut (StdOut) to the max
835          * supported size.
836          */
837         efi_console_set_mode();
838 
839     if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
840                            &cols, &rows) == EFI_SUCCESS )
841         efi_arch_console_init(cols, rows);
842 
843     gop = efi_get_gop(&gop_handle);
844 
845     if ( gop )
846     {
847         const char *cur = cmdline;
848         unsigned int width = 0, height = 0, depth = 0;
849         bool keep_current = false;
850 
851         while ( (cur = get_option(cur, "vga=")) != NULL )
852         {
853 #define VALID_TERMINATOR(c) \
854     (*(c) == ' ' || *(c) == '\t' || *(c) == '\0' || *(c) == ',')
855             if ( !strncmp(cur, "gfx-", 4) )
856             {
857                 width = simple_strtoul(cur + 4, &cur, 10);
858 
859                 if ( *cur == 'x' )
860                     height = simple_strtoul(cur + 1, &cur, 10);
861                 else
862                     goto error;
863 
864                 if ( *cur == 'x' )
865                     depth = simple_strtoul(cur + 1, &cur, 10);
866                 else
867                     goto error;
868 
869                 if ( !VALID_TERMINATOR(cur) )
870                 {
871                 error:
872                     PrintErr(L"Warning: Invalid gfx- option detected\r\n");
873                     width = height = depth = 0;
874                 }
875                 keep_current = false;
876             }
877             else if ( !strncmp(cur, "current", 7) && VALID_TERMINATOR(cur + 7) )
878                 keep_current = true;
879             else if ( !strncmp(cur, "keep", 4) && VALID_TERMINATOR(cur + 4) )
880             {
881                 /* Ignore, handled in later vga= parsing. */
882             }
883             else
884             {
885                 /* Fallback to defaults if unimplemented. */
886                 width = height = depth = 0;
887                 keep_current = false;
888                 PrintErr(L"Warning: Cannot use selected vga option\r\n");
889             }
890 #undef VALID_TERMINATOR
891         }
892 
893         if ( !keep_current )
894             gop_mode = efi_find_gop_mode(gop, width, height, depth);
895 
896         efi_arch_edid(gop_handle);
897     }
898 
899     efi_arch_edd();
900     efi_arch_cpu();
901 
902     efi_tables();
903     setup_efi_pci();
904     efi_variables();
905     efi_arch_memory_setup();
906 
907     if ( gop )
908         efi_set_gop_mode(gop, gop_mode);
909 
910     efi_relocate_esrt(SystemTable);
911 
912     efi_exit_boot(ImageHandle, SystemTable);
913 }
914 
915 /*
916  * Local variables:
917  * mode: C
918  * c-file-style: "BSD"
919  * c-basic-offset: 4
920  * indent-tabs-mode: nil
921  * End:
922  */
923