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