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