xref: /linux/arch/arm64/kernel/efi-header.S (revision 3c66bb1918c262dd52fb4221a8d372619c5da70a)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
2b5f4a214SArd Biesheuvel/*
3b5f4a214SArd Biesheuvel * Copyright (C) 2013 - 2017 Linaro, Ltd.
4b5f4a214SArd Biesheuvel * Copyright (C) 2013, 2014 Red Hat, Inc.
5b5f4a214SArd Biesheuvel */
6b5f4a214SArd Biesheuvel
7f1eb542fSArd Biesheuvel#include <linux/pe.h>
8f1eb542fSArd Biesheuvel#include <linux/sizes.h>
9f1eb542fSArd Biesheuvel
107919385bSArd Biesheuvel	.macro	efi_signature_nop
117919385bSArd Biesheuvel#ifdef CONFIG_EFI
127919385bSArd Biesheuvel.L_head:
137919385bSArd Biesheuvel	/*
147919385bSArd Biesheuvel	 * This ccmp instruction has no meaningful effect except that
157919385bSArd Biesheuvel	 * its opcode forms the magic "MZ" signature required by UEFI.
167919385bSArd Biesheuvel	 */
177919385bSArd Biesheuvel	ccmp	x18, #0, #0xd, pl
187919385bSArd Biesheuvel#else
197919385bSArd Biesheuvel	/*
207919385bSArd Biesheuvel	 * Bootloaders may inspect the opcode at the start of the kernel
217919385bSArd Biesheuvel	 * image to decide if the kernel is capable of booting via UEFI.
227919385bSArd Biesheuvel	 * So put an ordinary NOP here, not the "MZ.." pseudo-nop above.
237919385bSArd Biesheuvel	 */
247919385bSArd Biesheuvel	nop
257919385bSArd Biesheuvel#endif
267919385bSArd Biesheuvel	.endm
277919385bSArd Biesheuvel
28b5f4a214SArd Biesheuvel	.macro	__EFI_PE_HEADER
297919385bSArd Biesheuvel#ifdef CONFIG_EFI
307919385bSArd Biesheuvel	.set	.Lpe_header_offset, . - .L_head
31f1eb542fSArd Biesheuvel	.long	PE_MAGIC
32f1eb542fSArd Biesheuvel	.short	IMAGE_FILE_MACHINE_ARM64		// Machine
33b50a3225SArd Biesheuvel	.short	.Lsection_count				// NumberOfSections
34b5f4a214SArd Biesheuvel	.long	0 					// TimeDateStamp
35b5f4a214SArd Biesheuvel	.long	0					// PointerToSymbolTable
36f328ba47SArd Biesheuvel	.long	0					// NumberOfSymbols
37b50a3225SArd Biesheuvel	.short	.Lsection_table - .Loptional_header	// SizeOfOptionalHeader
38f1eb542fSArd Biesheuvel	.short	IMAGE_FILE_DEBUG_STRIPPED | \
39f1eb542fSArd Biesheuvel		IMAGE_FILE_EXECUTABLE_IMAGE | \
40f1eb542fSArd Biesheuvel		IMAGE_FILE_LINE_NUMS_STRIPPED		// Characteristics
41f1eb542fSArd Biesheuvel
42b50a3225SArd Biesheuvel.Loptional_header:
43f1eb542fSArd Biesheuvel	.short	PE_OPT_MAGIC_PE32PLUS			// PE32+ format
44b5f4a214SArd Biesheuvel	.byte	0x02					// MajorLinkerVersion
45b5f4a214SArd Biesheuvel	.byte	0x14					// MinorLinkerVersion
46b50a3225SArd Biesheuvel	.long	__initdata_begin - .Lefi_header_end	// SizeOfCode
47cad27ef2SArd Biesheuvel	.long	__pecoff_data_size			// SizeOfInitializedData
48b5f4a214SArd Biesheuvel	.long	0					// SizeOfUninitializedData
497919385bSArd Biesheuvel	.long	__efistub_efi_pe_entry - .L_head	// AddressOfEntryPoint
507919385bSArd Biesheuvel	.long	.Lefi_header_end - .L_head		// BaseOfCode
51b5f4a214SArd Biesheuvel
52b5f4a214SArd Biesheuvel	.quad	0					// ImageBase
5376085affSArd Biesheuvel	.long	SEGMENT_ALIGN				// SectionAlignment
54b5f4a214SArd Biesheuvel	.long	PECOFF_FILE_ALIGNMENT			// FileAlignment
55b5f4a214SArd Biesheuvel	.short	0					// MajorOperatingSystemVersion
56b5f4a214SArd Biesheuvel	.short	0					// MinorOperatingSystemVersion
57148d3f71SArd Biesheuvel	.short	LINUX_EFISTUB_MAJOR_VERSION		// MajorImageVersion
58148d3f71SArd Biesheuvel	.short	LINUX_EFISTUB_MINOR_VERSION		// MinorImageVersion
59b5f4a214SArd Biesheuvel	.short	0					// MajorSubsystemVersion
60b5f4a214SArd Biesheuvel	.short	0					// MinorSubsystemVersion
61b5f4a214SArd Biesheuvel	.long	0					// Win32VersionValue
62b5f4a214SArd Biesheuvel
637919385bSArd Biesheuvel	.long	_end - .L_head				// SizeOfImage
64b5f4a214SArd Biesheuvel
65b5f4a214SArd Biesheuvel	// Everything before the kernel image is considered part of the header
667919385bSArd Biesheuvel	.long	.Lefi_header_end - .L_head		// SizeOfHeaders
67b5f4a214SArd Biesheuvel	.long	0					// CheckSum
68f1eb542fSArd Biesheuvel	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION		// Subsystem
69*3c66bb19SArd Biesheuvel	.short	IMAGE_DLL_CHARACTERISTICS_NX_COMPAT	// DllCharacteristics
70b5f4a214SArd Biesheuvel	.quad	0					// SizeOfStackReserve
71b5f4a214SArd Biesheuvel	.quad	0					// SizeOfStackCommit
72b5f4a214SArd Biesheuvel	.quad	0					// SizeOfHeapReserve
73b5f4a214SArd Biesheuvel	.quad	0					// SizeOfHeapCommit
74b5f4a214SArd Biesheuvel	.long	0					// LoaderFlags
75b50a3225SArd Biesheuvel	.long	(.Lsection_table - .) / 8		// NumberOfRvaAndSizes
76b5f4a214SArd Biesheuvel
77b5f4a214SArd Biesheuvel	.quad	0					// ExportTable
78b5f4a214SArd Biesheuvel	.quad	0					// ImportTable
79b5f4a214SArd Biesheuvel	.quad	0					// ResourceTable
80b5f4a214SArd Biesheuvel	.quad	0					// ExceptionTable
81b5f4a214SArd Biesheuvel	.quad	0					// CertificationTable
82b5f4a214SArd Biesheuvel	.quad	0					// BaseRelocationTable
83b5f4a214SArd Biesheuvel
84b5f4a214SArd Biesheuvel#ifdef CONFIG_DEBUG_EFI
857919385bSArd Biesheuvel	.long	.Lefi_debug_table - .L_head		// DebugTable
86b50a3225SArd Biesheuvel	.long	.Lefi_debug_table_size
87b5f4a214SArd Biesheuvel#endif
88b5f4a214SArd Biesheuvel
89b5f4a214SArd Biesheuvel	// Section table
90b50a3225SArd Biesheuvel.Lsection_table:
91f1eb542fSArd Biesheuvel	.ascii	".text\0\0\0"
92b50a3225SArd Biesheuvel	.long	__initdata_begin - .Lefi_header_end	// VirtualSize
937919385bSArd Biesheuvel	.long	.Lefi_header_end - .L_head		// VirtualAddress
94b50a3225SArd Biesheuvel	.long	__initdata_begin - .Lefi_header_end	// SizeOfRawData
957919385bSArd Biesheuvel	.long	.Lefi_header_end - .L_head		// PointerToRawData
96b5f4a214SArd Biesheuvel
97b5f4a214SArd Biesheuvel	.long	0					// PointerToRelocations
98b5f4a214SArd Biesheuvel	.long	0					// PointerToLineNumbers
99b5f4a214SArd Biesheuvel	.short	0					// NumberOfRelocations
100b5f4a214SArd Biesheuvel	.short	0					// NumberOfLineNumbers
101f1eb542fSArd Biesheuvel	.long	IMAGE_SCN_CNT_CODE | \
102cad27ef2SArd Biesheuvel		IMAGE_SCN_MEM_READ | \
103cad27ef2SArd Biesheuvel		IMAGE_SCN_MEM_EXECUTE			// Characteristics
104cad27ef2SArd Biesheuvel
105cad27ef2SArd Biesheuvel	.ascii	".data\0\0\0"
106cad27ef2SArd Biesheuvel	.long	__pecoff_data_size			// VirtualSize
1077919385bSArd Biesheuvel	.long	__initdata_begin - .L_head		// VirtualAddress
108cad27ef2SArd Biesheuvel	.long	__pecoff_data_rawsize			// SizeOfRawData
1097919385bSArd Biesheuvel	.long	__initdata_begin - .L_head		// PointerToRawData
110cad27ef2SArd Biesheuvel
111cad27ef2SArd Biesheuvel	.long	0					// PointerToRelocations
112cad27ef2SArd Biesheuvel	.long	0					// PointerToLineNumbers
113cad27ef2SArd Biesheuvel	.short	0					// NumberOfRelocations
114cad27ef2SArd Biesheuvel	.short	0					// NumberOfLineNumbers
115cad27ef2SArd Biesheuvel	.long	IMAGE_SCN_CNT_INITIALIZED_DATA | \
116f1eb542fSArd Biesheuvel		IMAGE_SCN_MEM_READ | \
117f1eb542fSArd Biesheuvel		IMAGE_SCN_MEM_WRITE			// Characteristics
118f1eb542fSArd Biesheuvel
119b50a3225SArd Biesheuvel	.set	.Lsection_count, (. - .Lsection_table) / 40
120b5f4a214SArd Biesheuvel
121b5f4a214SArd Biesheuvel#ifdef CONFIG_DEBUG_EFI
122b5f4a214SArd Biesheuvel	/*
123b5f4a214SArd Biesheuvel	 * The debug table is referenced via its Relative Virtual Address (RVA),
124b5f4a214SArd Biesheuvel	 * which is only defined for those parts of the image that are covered
125b5f4a214SArd Biesheuvel	 * by a section declaration. Since this header is not covered by any
126b5f4a214SArd Biesheuvel	 * section, the debug table must be emitted elsewhere. So stick it in
127b5f4a214SArd Biesheuvel	 * the .init.rodata section instead.
128b5f4a214SArd Biesheuvel	 *
129b5f4a214SArd Biesheuvel	 * Note that the EFI debug entry itself may legally have a zero RVA,
130b5f4a214SArd Biesheuvel	 * which means we can simply put it right after the section headers.
131b5f4a214SArd Biesheuvel	 */
132b5f4a214SArd Biesheuvel	__INITRODATA
133b5f4a214SArd Biesheuvel
134b5f4a214SArd Biesheuvel	.align	2
135b50a3225SArd Biesheuvel.Lefi_debug_table:
136b5f4a214SArd Biesheuvel	// EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
137b5f4a214SArd Biesheuvel	.long	0					// Characteristics
138b5f4a214SArd Biesheuvel	.long	0					// TimeDateStamp
139b5f4a214SArd Biesheuvel	.short	0					// MajorVersion
140b5f4a214SArd Biesheuvel	.short	0					// MinorVersion
141f1eb542fSArd Biesheuvel	.long	IMAGE_DEBUG_TYPE_CODEVIEW		// Type
142b50a3225SArd Biesheuvel	.long	.Lefi_debug_entry_size			// SizeOfData
143b5f4a214SArd Biesheuvel	.long	0					// RVA
1447919385bSArd Biesheuvel	.long	.Lefi_debug_entry - .L_head		// FileOffset
145b5f4a214SArd Biesheuvel
146b50a3225SArd Biesheuvel	.set	.Lefi_debug_table_size, . - .Lefi_debug_table
147b5f4a214SArd Biesheuvel	.previous
148b5f4a214SArd Biesheuvel
149b50a3225SArd Biesheuvel.Lefi_debug_entry:
150b5f4a214SArd Biesheuvel	// EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
151b5f4a214SArd Biesheuvel	.ascii	"NB10"					// Signature
152b5f4a214SArd Biesheuvel	.long	0					// Unknown
153b5f4a214SArd Biesheuvel	.long	0					// Unknown2
154b5f4a214SArd Biesheuvel	.long	0					// Unknown3
155b5f4a214SArd Biesheuvel
156b5f4a214SArd Biesheuvel	.asciz	VMLINUX_PATH
157b5f4a214SArd Biesheuvel
158b50a3225SArd Biesheuvel	.set	.Lefi_debug_entry_size, . - .Lefi_debug_entry
159b5f4a214SArd Biesheuvel#endif
160b5f4a214SArd Biesheuvel
161a2d50c1cSArd Biesheuvel	.balign	SEGMENT_ALIGN
162b50a3225SArd Biesheuvel.Lefi_header_end:
1637919385bSArd Biesheuvel#else
1647919385bSArd Biesheuvel	.set	.Lpe_header_offset, 0x0
1657919385bSArd Biesheuvel#endif
166b5f4a214SArd Biesheuvel	.endm
167