xref: /openbmc/u-boot/arch/riscv/lib/crt0_riscv_efi.S (revision f388e3bed7318efe97058b673801dda6f563d319)
17215787cSRick Chen/* SPDX-License-Identifier: GPL-2.0+ */
2493d1e88SAlexander Graf/*
3493d1e88SAlexander Graf * crt0-efi-riscv.S - PE/COFF header for RISC-V EFI applications
4493d1e88SAlexander Graf *
5493d1e88SAlexander Graf * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
6493d1e88SAlexander Graf * Copright (C) 2018 Alexander Graf <agraf@suse.de>
7493d1e88SAlexander Graf *
8493d1e88SAlexander Graf * This file is inspired by arch/arm/lib/crt0_aarch64_efi.S
9493d1e88SAlexander Graf */
10493d1e88SAlexander Graf
11493d1e88SAlexander Graf#include <asm-generic/pe.h>
12493d1e88SAlexander Graf
13493d1e88SAlexander Graf#if __riscv_xlen == 64
14493d1e88SAlexander Graf#define SIZE_LONG	8
15493d1e88SAlexander Graf#define SAVE_LONG(reg, idx)	sd	reg, (idx*SIZE_LONG)(sp)
16493d1e88SAlexander Graf#define LOAD_LONG(reg, idx)	ld	reg, (idx*SIZE_LONG)(sp)
17493d1e88SAlexander Graf#define PE_MACHINE	0x5064
18493d1e88SAlexander Graf#else
19493d1e88SAlexander Graf#define SIZE_LONG	4
20493d1e88SAlexander Graf#define SAVE_LONG(reg, idx)	sw	reg, (idx*SIZE_LONG)(sp)
21493d1e88SAlexander Graf#define LOAD_LONG(reg, idx)	lw	reg, (idx*SIZE_LONG)(sp)
22493d1e88SAlexander Graf#define PE_MACHINE	0x5032
23493d1e88SAlexander Graf#endif
24493d1e88SAlexander Graf
25493d1e88SAlexander Graf
26493d1e88SAlexander Graf	.section	.text.head
27493d1e88SAlexander Graf
28493d1e88SAlexander Graf	/*
29493d1e88SAlexander Graf	 * Magic "MZ" signature for PE/COFF
30493d1e88SAlexander Graf	 */
31493d1e88SAlexander Graf	.globl	ImageBase
32493d1e88SAlexander GrafImageBase:
33493d1e88SAlexander Graf	.ascii	"MZ"
34493d1e88SAlexander Graf	.skip	58				/* 'MZ' + pad + offset == 64 */
35493d1e88SAlexander Graf	.long	pe_header - ImageBase		/* Offset to the PE header */
36493d1e88SAlexander Grafpe_header:
37493d1e88SAlexander Graf	.ascii	"PE"
38493d1e88SAlexander Graf	.short	0
39493d1e88SAlexander Grafcoff_header:
40493d1e88SAlexander Graf	.short	PE_MACHINE			/* RISC-V 64/32-bit */
41493d1e88SAlexander Graf	.short	2				/* nr_sections */
42493d1e88SAlexander Graf	.long	0				/* TimeDateStamp */
43493d1e88SAlexander Graf	.long	0				/* PointerToSymbolTable */
44*a33a4efdSBin Meng	.long	0				/* NumberOfSymbols */
45493d1e88SAlexander Graf	.short	section_table - optional_header	/* SizeOfOptionalHeader */
46*a33a4efdSBin Meng	/* Characteristics */
47*a33a4efdSBin Meng	.short	(IMAGE_FILE_EXECUTABLE_IMAGE | \
48*a33a4efdSBin Meng		 IMAGE_FILE_LINE_NUMS_STRIPPED | \
49*a33a4efdSBin Meng		 IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
50*a33a4efdSBin Meng		 IMAGE_FILE_DEBUG_STRIPPED)
51493d1e88SAlexander Grafoptional_header:
52493d1e88SAlexander Graf	.short	0x20b				/* PE32+ format */
53493d1e88SAlexander Graf	.byte	0x02				/* MajorLinkerVersion */
54493d1e88SAlexander Graf	.byte	0x14				/* MinorLinkerVersion */
55493d1e88SAlexander Graf	.long	_edata - _start			/* SizeOfCode */
56493d1e88SAlexander Graf	.long	0				/* SizeOfInitializedData */
57493d1e88SAlexander Graf	.long	0				/* SizeOfUninitializedData */
58493d1e88SAlexander Graf	.long	_start - ImageBase		/* AddressOfEntryPoint */
59493d1e88SAlexander Graf	.long	_start - ImageBase		/* BaseOfCode */
60493d1e88SAlexander Graf
61493d1e88SAlexander Grafextra_header_fields:
62493d1e88SAlexander Graf	.quad	0				/* ImageBase */
63493d1e88SAlexander Graf	.long	0x20				/* SectionAlignment */
64493d1e88SAlexander Graf	.long	0x8				/* FileAlignment */
65493d1e88SAlexander Graf	.short	0				/* MajorOperatingSystemVersion */
66493d1e88SAlexander Graf	.short	0				/* MinorOperatingSystemVersion */
67493d1e88SAlexander Graf	.short	0				/* MajorImageVersion */
68493d1e88SAlexander Graf	.short	0				/* MinorImageVersion */
69493d1e88SAlexander Graf	.short	0				/* MajorSubsystemVersion */
70493d1e88SAlexander Graf	.short	0				/* MinorSubsystemVersion */
71493d1e88SAlexander Graf	.long	0				/* Win32VersionValue */
72493d1e88SAlexander Graf
73493d1e88SAlexander Graf	.long	_edata - ImageBase		/* SizeOfImage */
74493d1e88SAlexander Graf
75493d1e88SAlexander Graf	/*
76493d1e88SAlexander Graf	 * Everything before the kernel image is considered part of the header
77493d1e88SAlexander Graf	 */
78493d1e88SAlexander Graf	.long	_start - ImageBase		/* SizeOfHeaders */
79493d1e88SAlexander Graf	.long	0				/* CheckSum */
80493d1e88SAlexander Graf	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION /* Subsystem */
81493d1e88SAlexander Graf	.short	0				/* DllCharacteristics */
82493d1e88SAlexander Graf	.quad	0				/* SizeOfStackReserve */
83493d1e88SAlexander Graf	.quad	0				/* SizeOfStackCommit */
84493d1e88SAlexander Graf	.quad	0				/* SizeOfHeapReserve */
85493d1e88SAlexander Graf	.quad	0				/* SizeOfHeapCommit */
86493d1e88SAlexander Graf	.long	0				/* LoaderFlags */
87493d1e88SAlexander Graf	.long	0x6				/* NumberOfRvaAndSizes */
88493d1e88SAlexander Graf
89493d1e88SAlexander Graf	.quad	0				/* ExportTable */
90493d1e88SAlexander Graf	.quad	0				/* ImportTable */
91493d1e88SAlexander Graf	.quad	0				/* ResourceTable */
92493d1e88SAlexander Graf	.quad	0				/* ExceptionTable */
93493d1e88SAlexander Graf	.quad	0				/* CertificationTable */
94493d1e88SAlexander Graf	.quad	0				/* BaseRelocationTable */
95493d1e88SAlexander Graf
96493d1e88SAlexander Graf	/* Section table */
97493d1e88SAlexander Grafsection_table:
98493d1e88SAlexander Graf
99493d1e88SAlexander Graf	/*
100493d1e88SAlexander Graf	 * The EFI application loader requires a relocation section
101493d1e88SAlexander Graf	 * because EFI applications must be relocatable.  This is a
102493d1e88SAlexander Graf	 * dummy section as far as we are concerned.
103493d1e88SAlexander Graf	 */
104493d1e88SAlexander Graf	.ascii	".reloc"
105493d1e88SAlexander Graf	.byte	0
106493d1e88SAlexander Graf	.byte	0			/* end of 0 padding of section name */
107493d1e88SAlexander Graf	.long	0
108493d1e88SAlexander Graf	.long	0
109493d1e88SAlexander Graf	.long	0			/* SizeOfRawData */
110493d1e88SAlexander Graf	.long	0			/* PointerToRawData */
111493d1e88SAlexander Graf	.long	0			/* PointerToRelocations */
112493d1e88SAlexander Graf	.long	0			/* PointerToLineNumbers */
113493d1e88SAlexander Graf	.short	0			/* NumberOfRelocations */
114493d1e88SAlexander Graf	.short	0			/* NumberOfLineNumbers */
115493d1e88SAlexander Graf	.long	0x42100040		/* Characteristics (section flags) */
116493d1e88SAlexander Graf
117493d1e88SAlexander Graf
118493d1e88SAlexander Graf	.ascii	".text"
119493d1e88SAlexander Graf	.byte	0
120493d1e88SAlexander Graf	.byte	0
121493d1e88SAlexander Graf	.byte	0			/* end of 0 padding of section name */
122493d1e88SAlexander Graf	.long	_edata - _start		/* VirtualSize */
123493d1e88SAlexander Graf	.long	_start - ImageBase	/* VirtualAddress */
124493d1e88SAlexander Graf	.long	_edata - _start		/* SizeOfRawData */
125493d1e88SAlexander Graf	.long	_start - ImageBase	/* PointerToRawData */
126493d1e88SAlexander Graf
127493d1e88SAlexander Graf	.long	0		/* PointerToRelocations (0 for executables) */
128493d1e88SAlexander Graf	.long	0		/* PointerToLineNumbers (0 for executables) */
129493d1e88SAlexander Graf	.short	0		/* NumberOfRelocations  (0 for executables) */
130493d1e88SAlexander Graf	.short	0		/* NumberOfLineNumbers  (0 for executables) */
131493d1e88SAlexander Graf	.long	0xe0500020	/* Characteristics (section flags) */
132493d1e88SAlexander Graf
133493d1e88SAlexander Graf_start:
134493d1e88SAlexander Graf	addi		sp, sp, -(SIZE_LONG * 3)
135493d1e88SAlexander Graf	SAVE_LONG(a0, 0)
136493d1e88SAlexander Graf	SAVE_LONG(a1, 1)
137493d1e88SAlexander Graf	SAVE_LONG(ra, 2)
138493d1e88SAlexander Graf
139493d1e88SAlexander Graf	lla		a0, ImageBase
140493d1e88SAlexander Graf	lla		a1, _DYNAMIC
141493d1e88SAlexander Graf	call		_relocate
142493d1e88SAlexander Graf	bne		a0, zero, 0f
143493d1e88SAlexander Graf
144493d1e88SAlexander Graf	LOAD_LONG(a1, 1)
145493d1e88SAlexander Graf	LOAD_LONG(a0, 0)
146493d1e88SAlexander Graf	call		efi_main
147493d1e88SAlexander Graf
148493d1e88SAlexander Graf	LOAD_LONG(ra, 2)
149493d1e88SAlexander Graf
150493d1e88SAlexander Graf0:	addi		sp, sp, (SIZE_LONG * 3)
151493d1e88SAlexander Graf	ret
152