xref: /openbmc/u-boot/arch/riscv/lib/crt0_riscv_efi.S (revision 493d1e88b676675e0c2a8614abcba0dcbb9befa4)
1*493d1e88SAlexander Graf/*
2*493d1e88SAlexander Graf * crt0-efi-riscv.S - PE/COFF header for RISC-V EFI applications
3*493d1e88SAlexander Graf *
4*493d1e88SAlexander Graf * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
5*493d1e88SAlexander Graf * Copright (C) 2018 Alexander Graf <agraf@suse.de>
6*493d1e88SAlexander Graf *
7*493d1e88SAlexander Graf * SPDX-License-Identifier:     GPL-2.0+     BSD-2-Clause
8*493d1e88SAlexander Graf *
9*493d1e88SAlexander Graf * This file is inspired by arch/arm/lib/crt0_aarch64_efi.S
10*493d1e88SAlexander Graf */
11*493d1e88SAlexander Graf
12*493d1e88SAlexander Graf#include <asm-generic/pe.h>
13*493d1e88SAlexander Graf
14*493d1e88SAlexander Graf#if __riscv_xlen == 64
15*493d1e88SAlexander Graf#define SIZE_LONG	8
16*493d1e88SAlexander Graf#define SAVE_LONG(reg, idx)	sd	reg, (idx*SIZE_LONG)(sp)
17*493d1e88SAlexander Graf#define LOAD_LONG(reg, idx)	ld	reg, (idx*SIZE_LONG)(sp)
18*493d1e88SAlexander Graf#define PE_MACHINE	0x5064
19*493d1e88SAlexander Graf#else
20*493d1e88SAlexander Graf#define SIZE_LONG	4
21*493d1e88SAlexander Graf#define SAVE_LONG(reg, idx)	sw	reg, (idx*SIZE_LONG)(sp)
22*493d1e88SAlexander Graf#define LOAD_LONG(reg, idx)	lw	reg, (idx*SIZE_LONG)(sp)
23*493d1e88SAlexander Graf#define PE_MACHINE	0x5032
24*493d1e88SAlexander Graf#endif
25*493d1e88SAlexander Graf
26*493d1e88SAlexander Graf
27*493d1e88SAlexander Graf	.section	.text.head
28*493d1e88SAlexander Graf
29*493d1e88SAlexander Graf	/*
30*493d1e88SAlexander Graf	 * Magic "MZ" signature for PE/COFF
31*493d1e88SAlexander Graf	 */
32*493d1e88SAlexander Graf	.globl	ImageBase
33*493d1e88SAlexander GrafImageBase:
34*493d1e88SAlexander Graf	.ascii	"MZ"
35*493d1e88SAlexander Graf	.skip	58				/* 'MZ' + pad + offset == 64 */
36*493d1e88SAlexander Graf	.long	pe_header - ImageBase		/* Offset to the PE header */
37*493d1e88SAlexander Grafpe_header:
38*493d1e88SAlexander Graf	.ascii	"PE"
39*493d1e88SAlexander Graf	.short	0
40*493d1e88SAlexander Grafcoff_header:
41*493d1e88SAlexander Graf	.short	PE_MACHINE			/* RISC-V 64/32-bit */
42*493d1e88SAlexander Graf	.short	2				/* nr_sections */
43*493d1e88SAlexander Graf	.long	0				/* TimeDateStamp */
44*493d1e88SAlexander Graf	.long	0				/* PointerToSymbolTable */
45*493d1e88SAlexander Graf	.long	1				/* NumberOfSymbols */
46*493d1e88SAlexander Graf	.short	section_table - optional_header	/* SizeOfOptionalHeader */
47*493d1e88SAlexander Graf	/*
48*493d1e88SAlexander Graf	 * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
49*493d1e88SAlexander Graf	 * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
50*493d1e88SAlexander Graf	 */
51*493d1e88SAlexander Graf	.short	0x206
52*493d1e88SAlexander Grafoptional_header:
53*493d1e88SAlexander Graf	.short	0x20b				/* PE32+ format */
54*493d1e88SAlexander Graf	.byte	0x02				/* MajorLinkerVersion */
55*493d1e88SAlexander Graf	.byte	0x14				/* MinorLinkerVersion */
56*493d1e88SAlexander Graf	.long	_edata - _start			/* SizeOfCode */
57*493d1e88SAlexander Graf	.long	0				/* SizeOfInitializedData */
58*493d1e88SAlexander Graf	.long	0				/* SizeOfUninitializedData */
59*493d1e88SAlexander Graf	.long	_start - ImageBase		/* AddressOfEntryPoint */
60*493d1e88SAlexander Graf	.long	_start - ImageBase		/* BaseOfCode */
61*493d1e88SAlexander Graf
62*493d1e88SAlexander Grafextra_header_fields:
63*493d1e88SAlexander Graf	.quad	0				/* ImageBase */
64*493d1e88SAlexander Graf	.long	0x20				/* SectionAlignment */
65*493d1e88SAlexander Graf	.long	0x8				/* FileAlignment */
66*493d1e88SAlexander Graf	.short	0				/* MajorOperatingSystemVersion */
67*493d1e88SAlexander Graf	.short	0				/* MinorOperatingSystemVersion */
68*493d1e88SAlexander Graf	.short	0				/* MajorImageVersion */
69*493d1e88SAlexander Graf	.short	0				/* MinorImageVersion */
70*493d1e88SAlexander Graf	.short	0				/* MajorSubsystemVersion */
71*493d1e88SAlexander Graf	.short	0				/* MinorSubsystemVersion */
72*493d1e88SAlexander Graf	.long	0				/* Win32VersionValue */
73*493d1e88SAlexander Graf
74*493d1e88SAlexander Graf	.long	_edata - ImageBase		/* SizeOfImage */
75*493d1e88SAlexander Graf
76*493d1e88SAlexander Graf	/*
77*493d1e88SAlexander Graf	 * Everything before the kernel image is considered part of the header
78*493d1e88SAlexander Graf	 */
79*493d1e88SAlexander Graf	.long	_start - ImageBase		/* SizeOfHeaders */
80*493d1e88SAlexander Graf	.long	0				/* CheckSum */
81*493d1e88SAlexander Graf	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION /* Subsystem */
82*493d1e88SAlexander Graf	.short	0				/* DllCharacteristics */
83*493d1e88SAlexander Graf	.quad	0				/* SizeOfStackReserve */
84*493d1e88SAlexander Graf	.quad	0				/* SizeOfStackCommit */
85*493d1e88SAlexander Graf	.quad	0				/* SizeOfHeapReserve */
86*493d1e88SAlexander Graf	.quad	0				/* SizeOfHeapCommit */
87*493d1e88SAlexander Graf	.long	0				/* LoaderFlags */
88*493d1e88SAlexander Graf	.long	0x6				/* NumberOfRvaAndSizes */
89*493d1e88SAlexander Graf
90*493d1e88SAlexander Graf	.quad	0				/* ExportTable */
91*493d1e88SAlexander Graf	.quad	0				/* ImportTable */
92*493d1e88SAlexander Graf	.quad	0				/* ResourceTable */
93*493d1e88SAlexander Graf	.quad	0				/* ExceptionTable */
94*493d1e88SAlexander Graf	.quad	0				/* CertificationTable */
95*493d1e88SAlexander Graf	.quad	0				/* BaseRelocationTable */
96*493d1e88SAlexander Graf
97*493d1e88SAlexander Graf	/* Section table */
98*493d1e88SAlexander Grafsection_table:
99*493d1e88SAlexander Graf
100*493d1e88SAlexander Graf	/*
101*493d1e88SAlexander Graf	 * The EFI application loader requires a relocation section
102*493d1e88SAlexander Graf	 * because EFI applications must be relocatable.  This is a
103*493d1e88SAlexander Graf	 * dummy section as far as we are concerned.
104*493d1e88SAlexander Graf	 */
105*493d1e88SAlexander Graf	.ascii	".reloc"
106*493d1e88SAlexander Graf	.byte	0
107*493d1e88SAlexander Graf	.byte	0			/* end of 0 padding of section name */
108*493d1e88SAlexander Graf	.long	0
109*493d1e88SAlexander Graf	.long	0
110*493d1e88SAlexander Graf	.long	0			/* SizeOfRawData */
111*493d1e88SAlexander Graf	.long	0			/* PointerToRawData */
112*493d1e88SAlexander Graf	.long	0			/* PointerToRelocations */
113*493d1e88SAlexander Graf	.long	0			/* PointerToLineNumbers */
114*493d1e88SAlexander Graf	.short	0			/* NumberOfRelocations */
115*493d1e88SAlexander Graf	.short	0			/* NumberOfLineNumbers */
116*493d1e88SAlexander Graf	.long	0x42100040		/* Characteristics (section flags) */
117*493d1e88SAlexander Graf
118*493d1e88SAlexander Graf
119*493d1e88SAlexander Graf	.ascii	".text"
120*493d1e88SAlexander Graf	.byte	0
121*493d1e88SAlexander Graf	.byte	0
122*493d1e88SAlexander Graf	.byte	0			/* end of 0 padding of section name */
123*493d1e88SAlexander Graf	.long	_edata - _start		/* VirtualSize */
124*493d1e88SAlexander Graf	.long	_start - ImageBase	/* VirtualAddress */
125*493d1e88SAlexander Graf	.long	_edata - _start		/* SizeOfRawData */
126*493d1e88SAlexander Graf	.long	_start - ImageBase	/* PointerToRawData */
127*493d1e88SAlexander Graf
128*493d1e88SAlexander Graf	.long	0		/* PointerToRelocations (0 for executables) */
129*493d1e88SAlexander Graf	.long	0		/* PointerToLineNumbers (0 for executables) */
130*493d1e88SAlexander Graf	.short	0		/* NumberOfRelocations  (0 for executables) */
131*493d1e88SAlexander Graf	.short	0		/* NumberOfLineNumbers  (0 for executables) */
132*493d1e88SAlexander Graf	.long	0xe0500020	/* Characteristics (section flags) */
133*493d1e88SAlexander Graf
134*493d1e88SAlexander Graf_start:
135*493d1e88SAlexander Graf	addi		sp, sp, -(SIZE_LONG * 3)
136*493d1e88SAlexander Graf	SAVE_LONG(a0, 0)
137*493d1e88SAlexander Graf	SAVE_LONG(a1, 1)
138*493d1e88SAlexander Graf	SAVE_LONG(ra, 2)
139*493d1e88SAlexander Graf
140*493d1e88SAlexander Graf	lla		a0, ImageBase
141*493d1e88SAlexander Graf	lla		a1, _DYNAMIC
142*493d1e88SAlexander Graf	call		_relocate
143*493d1e88SAlexander Graf	bne		a0, zero, 0f
144*493d1e88SAlexander Graf
145*493d1e88SAlexander Graf	LOAD_LONG(a1, 1)
146*493d1e88SAlexander Graf	LOAD_LONG(a0, 0)
147*493d1e88SAlexander Graf	call		efi_main
148*493d1e88SAlexander Graf
149*493d1e88SAlexander Graf	LOAD_LONG(ra, 2)
150*493d1e88SAlexander Graf
151*493d1e88SAlexander Graf0:	addi		sp, sp, (SIZE_LONG * 3)
152*493d1e88SAlexander Graf	ret
153