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