root/src/system/boot/platform/efi/arch/riscv64/crt0-efi-riscv64.S
/*-
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
 *
 * Copyright (c) 2020 Mitchell Horne <mhorne@FreeBSD.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD$
 */

        .section        .text.head

        /*
         * Magic "MZ" signature for PE/COFF
         */
        .globl  ImageBase
ImageBase:
        .ascii  "MZ"
        .skip   58                              // 'MZ' + pad + offset == 64
        .long   pe_header - ImageBase           // Offset to the PE header.
pe_header:
        .ascii  "PE"
        .short  0
coff_header:
        .short  0x5064                  // RISCV64
        .short  2                               // nr_sections
        .long   0                               // TimeDateStamp
        .long   0                               // PointerToSymbolTable
        .long   0                               // NumberOfSymbols
        .short  section_table - optional_header // SizeOfOptionalHeader
        .short  0x20e                   // Characteristics.
                                                        // IMAGE_FILE_DEBUG_STRIPPED |
                                                        // IMAGE_FILE_EXECUTABLE_IMAGE |
                                                        // IMAGE_FILE_LOCAL_SYMS_STRIPPED |
                                                        // IMAGE_FILE_LINE_NUMS_STRIPPED
optional_header:
        .short  0x20b                           // PE32+ format
        .byte   0x02                            // MajorLinkerVersion
        .byte   0x14                            // MinorLinkerVersion
        .long   _edata - _start                 // SizeOfCode
        .long   0                               // SizeOfInitializedData
        .long   0                               // SizeOfUninitializedData
        .long   _start - ImageBase              // AddressOfEntryPoint
        .long   _start - ImageBase              // BaseOfCode

extra_header_fields:
        .quad   0                               // ImageBase
        .long   32                              // SectionAlignment
        .long   8                               // FileAlignment

        .short  0                               // MajorOperatingSystemVersion
        .short  0                               // MinorOperatingSystemVersion
        .short  0                               // MajorImageVersion
        .short  0                               // MinorImageVersion
        .short  0                               // MajorSubsystemVersion
        .short  0                               // MinorSubsystemVersion
        .long   0                               // Win32VersionValue

        .long   _edata - ImageBase              // SizeOfImage

        // Everything before the kernel image is considered part of the header
        .long   _start - ImageBase              // SizeOfHeaders
        .long   0                               // CheckSum
        .short  10                              // Subsystem (EFI)
        .short  0                               // DllCharacteristics
        .quad   0                               // SizeOfStackReserve
        .quad   0                               // SizeOfStackCommit
        .quad   0                               // SizeOfHeapReserve
        .quad   0                               // SizeOfHeapCommit
        .long   0                               // LoaderFlags
        .long   16                              // NumberOfRvaAndSizes

        .quad   0                               // ExportTable
        .quad   0                               // ImportTable
        .quad   0                               // ResourceTable
        .quad   0                               // ExceptionTable
        .quad   0                               // CertificationTable
        .quad   0                               // BaseRelocationTable
        .quad   0                               // Debug
        .quad   0                               // Architecture
        .quad   0                               // Global Ptr
        .quad   0                               // TLS Table
        .quad   0                               // Load Config Table
        .quad   0                               // Bound Import
        .quad   0                               // IAT
        .quad   0                               // Delay Import Descriptor
        .quad   0                               // CLR Runtime Header
        .quad   0                               // Reserved

        // Section table
section_table:

        /*
         * The EFI application loader requires a relocation section
         * because EFI applications must be relocatable.  This is a
         * dummy section as far as we are concerned.
         */
        .ascii  ".reloc"
        .byte   0
        .byte   0                       // end of 0 padding of section name
        .long   0
        .long   0
        .long   0                       // SizeOfRawData
        .long   0                       // PointerToRawData
        .long   0                       // PointerToRelocations
        .long   0                       // PointerToLineNumbers
        .short  0                       // NumberOfRelocations
        .short  0                       // NumberOfLineNumbers
        .long   0x42100040              // Characteristics (section flags)


        .ascii  ".text"
        .byte   0
        .byte   0
        .byte   0                       // end of 0 padding of section name
        .long   _edata - _start         // VirtualSize
        .long   _start - ImageBase      // VirtualAddress
        .long   _edata - _start         // SizeOfRawData
        .long   _start - ImageBase      // PointerToRawData

        .long   0               // PointerToRelocations (0 for executables)
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
        .long   0xe0500020      // Characteristics (section flags)

        .globl _start
_start:
        /* Save boot parameters to the stack */
        addi            sp, sp, -24
        sd                      a0, 0(sp)
        sd                      a1, 8(sp)
        sd                      ra, 16(sp)

        /* Run relocation */
        lla                     a0, ImageBase
        lla                     a1, _DYNAMIC
        call            _relocate
        bne                     a0, zero, 0f

        /* Call EFI code */
        ld                      a1, 8(sp)
        ld                      a0, 0(sp)
        call            efi_main

        ld                      ra, 16(sp)

0:      addi            sp, sp, 24
        ret