1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 281a0bc39SRoy Franz/* 3609eaf07SArd Biesheuvel * Copyright (C) 2013-2017 Linaro Ltd 481a0bc39SRoy Franz * Authors: Roy Franz <roy.franz@linaro.org> 581a0bc39SRoy Franz * Ard Biesheuvel <ard.biesheuvel@linaro.org> 681a0bc39SRoy Franz */ 781a0bc39SRoy Franz 8609eaf07SArd Biesheuvel#include <linux/pe.h> 9609eaf07SArd Biesheuvel#include <linux/sizes.h> 10609eaf07SArd Biesheuvel 1181a0bc39SRoy Franz .macro __nop 1260ce2858SArd Biesheuvel AR_CLASS( mov r0, r0 ) 1360ce2858SArd Biesheuvel M_CLASS( nop.w ) 14*a92882a4SAndre Przywara .endm 15*a92882a4SAndre Przywara 16*a92882a4SAndre Przywara .macro __initial_nops 17*a92882a4SAndre Przywara#ifdef CONFIG_EFI_STUB 18*a92882a4SAndre Przywara @ This is a two-instruction NOP, which happens to bear the 19*a92882a4SAndre Przywara @ PE/COFF signature "MZ" in the first two bytes, so the kernel 20*a92882a4SAndre Przywara @ is accepted as an EFI binary. Booting via the UEFI stub 21*a92882a4SAndre Przywara @ will not execute those instructions, but the ARM/Linux 22*a92882a4SAndre Przywara @ boot protocol does, so we need some NOPs here. 23*a92882a4SAndre Przywara .inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000 24*a92882a4SAndre Przywara eor r5, r5, 0x4d000 @ undo previous insn 25*a92882a4SAndre Przywara#else 26*a92882a4SAndre Przywara __nop 27*a92882a4SAndre Przywara __nop 2881a0bc39SRoy Franz#endif 2981a0bc39SRoy Franz .endm 3081a0bc39SRoy Franz 3181a0bc39SRoy Franz .macro __EFI_HEADER 3281a0bc39SRoy Franz#ifdef CONFIG_EFI_STUB 3381a0bc39SRoy Franz .set start_offset, __efi_start - start 3481a0bc39SRoy Franz .org start + 0x3c 3581a0bc39SRoy Franz @ 3681a0bc39SRoy Franz @ The PE header can be anywhere in the file, but for 3781a0bc39SRoy Franz @ simplicity we keep it together with the MSDOS header 3881a0bc39SRoy Franz @ The offset to the PE/COFF header needs to be at offset 3981a0bc39SRoy Franz @ 0x3C in the MSDOS header. 4081a0bc39SRoy Franz @ The only 2 fields of the MSDOS header that are used are this 4181a0bc39SRoy Franz @ PE/COFF offset, and the "MZ" bytes at offset 0x0. 4281a0bc39SRoy Franz @ 4381a0bc39SRoy Franz .long pe_header - start @ Offset to the PE header. 4481a0bc39SRoy Franz 4581a0bc39SRoy Franzpe_header: 46609eaf07SArd Biesheuvel .long PE_MAGIC 4781a0bc39SRoy Franz 4881a0bc39SRoy Franzcoff_header: 49609eaf07SArd Biesheuvel .short IMAGE_FILE_MACHINE_THUMB @ Machine 50609eaf07SArd Biesheuvel .short section_count @ NumberOfSections 5181a0bc39SRoy Franz .long 0 @ TimeDateStamp 5281a0bc39SRoy Franz .long 0 @ PointerToSymbolTable 534415f9f4SArd Biesheuvel .long 0 @ NumberOfSymbols 54609eaf07SArd Biesheuvel .short section_table - optional_header @ SizeOfOptionalHeader 55609eaf07SArd Biesheuvel .short IMAGE_FILE_32BIT_MACHINE | \ 56609eaf07SArd Biesheuvel IMAGE_FILE_DEBUG_STRIPPED | \ 57609eaf07SArd Biesheuvel IMAGE_FILE_EXECUTABLE_IMAGE | \ 58609eaf07SArd Biesheuvel IMAGE_FILE_LINE_NUMS_STRIPPED @ Characteristics 5981a0bc39SRoy Franz 60e4bae4d0SArd Biesheuvel#define __pecoff_code_size (__pecoff_data_start - __efi_start) 61e4bae4d0SArd Biesheuvel 6281a0bc39SRoy Franzoptional_header: 63609eaf07SArd Biesheuvel .short PE_OPT_MAGIC_PE32 @ PE32 format 6481a0bc39SRoy Franz .byte 0x02 @ MajorLinkerVersion 6581a0bc39SRoy Franz .byte 0x14 @ MinorLinkerVersion 66e4bae4d0SArd Biesheuvel .long __pecoff_code_size @ SizeOfCode 67e4bae4d0SArd Biesheuvel .long __pecoff_data_size @ SizeOfInitializedData 6881a0bc39SRoy Franz .long 0 @ SizeOfUninitializedData 696e99d321SArd Biesheuvel .long efi_pe_entry - start @ AddressOfEntryPoint 7081a0bc39SRoy Franz .long start_offset @ BaseOfCode 71e4bae4d0SArd Biesheuvel .long __pecoff_data_start - start @ BaseOfData 7281a0bc39SRoy Franz 7381a0bc39SRoy Franzextra_header_fields: 7481a0bc39SRoy Franz .long 0 @ ImageBase 75e4bae4d0SArd Biesheuvel .long SZ_4K @ SectionAlignment 76609eaf07SArd Biesheuvel .long SZ_512 @ FileAlignment 77609eaf07SArd Biesheuvel .short 0 @ MajorOsVersion 78609eaf07SArd Biesheuvel .short 0 @ MinorOsVersion 79148d3f71SArd Biesheuvel .short LINUX_EFISTUB_MAJOR_VERSION @ MajorImageVersion 80148d3f71SArd Biesheuvel .short LINUX_EFISTUB_MINOR_VERSION @ MinorImageVersion 8181a0bc39SRoy Franz .short 0 @ MajorSubsystemVersion 8281a0bc39SRoy Franz .short 0 @ MinorSubsystemVersion 8381a0bc39SRoy Franz .long 0 @ Win32VersionValue 8481a0bc39SRoy Franz 85e4bae4d0SArd Biesheuvel .long __pecoff_end - start @ SizeOfImage 8681a0bc39SRoy Franz .long start_offset @ SizeOfHeaders 8781a0bc39SRoy Franz .long 0 @ CheckSum 88609eaf07SArd Biesheuvel .short IMAGE_SUBSYSTEM_EFI_APPLICATION @ Subsystem 8981a0bc39SRoy Franz .short 0 @ DllCharacteristics 9081a0bc39SRoy Franz .long 0 @ SizeOfStackReserve 9181a0bc39SRoy Franz .long 0 @ SizeOfStackCommit 9281a0bc39SRoy Franz .long 0 @ SizeOfHeapReserve 9381a0bc39SRoy Franz .long 0 @ SizeOfHeapCommit 9481a0bc39SRoy Franz .long 0 @ LoaderFlags 95609eaf07SArd Biesheuvel .long (section_table - .) / 8 @ NumberOfRvaAndSizes 9681a0bc39SRoy Franz 9781a0bc39SRoy Franz .quad 0 @ ExportTable 9881a0bc39SRoy Franz .quad 0 @ ImportTable 9981a0bc39SRoy Franz .quad 0 @ ResourceTable 10081a0bc39SRoy Franz .quad 0 @ ExceptionTable 10181a0bc39SRoy Franz .quad 0 @ CertificationTable 10281a0bc39SRoy Franz .quad 0 @ BaseRelocationTable 10381a0bc39SRoy Franz 10481a0bc39SRoy Franzsection_table: 10581a0bc39SRoy Franz .ascii ".text\0\0\0" 106e4bae4d0SArd Biesheuvel .long __pecoff_code_size @ VirtualSize 10781a0bc39SRoy Franz .long __efi_start @ VirtualAddress 108e4bae4d0SArd Biesheuvel .long __pecoff_code_size @ SizeOfRawData 10981a0bc39SRoy Franz .long __efi_start @ PointerToRawData 11081a0bc39SRoy Franz .long 0 @ PointerToRelocations 11181a0bc39SRoy Franz .long 0 @ PointerToLineNumbers 11281a0bc39SRoy Franz .short 0 @ NumberOfRelocations 11381a0bc39SRoy Franz .short 0 @ NumberOfLineNumbers 114609eaf07SArd Biesheuvel .long IMAGE_SCN_CNT_CODE | \ 115609eaf07SArd Biesheuvel IMAGE_SCN_MEM_READ | \ 116609eaf07SArd Biesheuvel IMAGE_SCN_MEM_EXECUTE @ Characteristics 117609eaf07SArd Biesheuvel 118e4bae4d0SArd Biesheuvel .ascii ".data\0\0\0" 119e4bae4d0SArd Biesheuvel .long __pecoff_data_size @ VirtualSize 120e4bae4d0SArd Biesheuvel .long __pecoff_data_start - start @ VirtualAddress 121e4bae4d0SArd Biesheuvel .long __pecoff_data_rawsize @ SizeOfRawData 122e4bae4d0SArd Biesheuvel .long __pecoff_data_start - start @ PointerToRawData 123e4bae4d0SArd Biesheuvel .long 0 @ PointerToRelocations 124e4bae4d0SArd Biesheuvel .long 0 @ PointerToLineNumbers 125e4bae4d0SArd Biesheuvel .short 0 @ NumberOfRelocations 126e4bae4d0SArd Biesheuvel .short 0 @ NumberOfLineNumbers 127e4bae4d0SArd Biesheuvel .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ 128e4bae4d0SArd Biesheuvel IMAGE_SCN_MEM_READ | \ 129e4bae4d0SArd Biesheuvel IMAGE_SCN_MEM_WRITE @ Characteristics 130e4bae4d0SArd Biesheuvel 131609eaf07SArd Biesheuvel .set section_count, (. - section_table) / 40 13281a0bc39SRoy Franz 133e4bae4d0SArd Biesheuvel .align 12 13481a0bc39SRoy Franz__efi_start: 13581a0bc39SRoy Franz#endif 13681a0bc39SRoy Franz .endm 137